import { Field, Cast, Opt } from "./Field" import { Key, KeyStore } from "./Key" import { NumberField } from "./NumberField"; import { ObservableMap, computed } from "mobx"; import { TextField } from "./TextField"; import { ListField } from "./ListField"; export class Document extends Field { private fields: ObservableMap = new ObservableMap(); static _untitledDocName = ""; @computed public get Title() { return this.GetFieldValue(KeyStore.Title, TextField, Document._untitledDocName); } GetField(key: Key, ignoreProto: boolean = false): Opt { let field: Opt; if (ignoreProto) { if (this.fields.has(key)) { field = this.fields.get(key); } } else { let doc: Opt = this; while (doc && !(doc.fields.has(key))) { doc = doc.GetPrototype(); } if (doc) { field = doc.fields.get(key); } } return field; } GetFieldT(key: Key, ctor: { new(...args: any[]): T }, ignoreProto: boolean = false): Opt { return Cast(this.GetField(key, ignoreProto), ctor); } GetFieldOrCreate(key: Key, ctor: { new(): T }, ignoreProto: boolean = false): T { const field = this.GetFieldT(key, ctor, ignoreProto); if (field) { return field; } const newField = new ctor(); this.SetField(key, newField); return newField; } GetFieldValue(key: Key, ctor: { new(): U }, defaultVal: T): T { let val = this.GetField(key); let vval = (val && val instanceof ctor) ? val.Data : defaultVal; return vval; } GetNumberField(key: Key, defaultVal: number): number { return this.GetFieldValue(key, NumberField, defaultVal); } GetTextField(key: Key, defaultVal: string): string { return this.GetFieldValue(key, TextField, defaultVal); } GetListField(key: Key, defaultVal: T[]): T[] { return this.GetFieldValue>(key, ListField, defaultVal) } SetField(key: Key, field: Field | undefined): void { if (field) { this.fields.set(key, field); } else { this.fields.delete(key); } } SetFieldValue(key: Key, value: any, ctor: { new(): T }): boolean { let field = this.GetField(key, true); if (field != null) { return field.TrySetValue(value); } else { field = new ctor(); if (field.TrySetValue(value)) { this.SetField(key, field); return true; } else { return false; } } } GetPrototype(): Opt { return this.GetFieldT(KeyStore.Prototype, Document, true); } GetAllPrototypes(): Document[] { let protos: Document[] = []; let doc: Opt = this; while (doc != null) { protos.push(doc); doc = doc.GetPrototype(); } return protos; } MakeDelegate(): Document { let delegate = new Document(); delegate.SetField(KeyStore.Prototype, this); return delegate; } TrySetValue(value: any): boolean { throw new Error("Method not implemented."); } GetValue() { throw new Error("Method not implemented."); } Copy(): Field { throw new Error("Method not implemented."); } }