import { TypeDescriptionMetadata } from './TypeDescriptionMetadata';
import { TypeDescriptionWellKnownType } from './TypeDescriptionWellKnownType';
import { IgCollection } from './IgCollection';
import { TypeRegistrar } from './type';
import { IgcComponentRendererContainerComponent } from './igc-component-renderer-container-component';
export class ComponentRendererAdapter {
    constructor() {
        this._platform = "Igc";
    }
    createObject(type, container, context) {
        var meta = context.getMetadata(type, "__qualifiedNameTS");
        if (meta) {
            type = meta.specificExternalType;
        }
        let typeName = "Igc" + type + "Component";
        if (TypeRegistrar.isRegistered(typeName)) {
            return TypeRegistrar.create(typeName);
        }
        let shortTypeName = "Igc" + type;
        if (TypeRegistrar.isRegistered(shortTypeName)) {
            return TypeRegistrar.create(shortTypeName);
        }
        if (TypeRegistrar.isRegistered(type)) {
            return TypeRegistrar.create(type);
        }
    }
    //createRootObject(type: string, container: any, context: TypeDescriptionContext, continueActions: (resumeRequired: boolean) => void) {
    //    let typeName = "Igr" + type;
    //    if (TypeRegistrar.isRegistered(typeName)) {
    //        let t = TypeRegistrar.get(typeName);
    //        let crc = container as IgrComponentRendererContainer;
    //        crc.createRootObject(t, continueActions);
    //    }
    //}
    createColorCollection(colors) {
        return colors;
    }
    createBrushCollection(brushes) {
        return brushes;
    }
    coerceToEnum(type, context, value) {
        return TypeDescriptionMetadata.camelize(value);
    }
    onUIThread(container, action) {
        action();
    }
    setOrUpdateCollectionOnTarget(container, propertyName, propertyMetadata, context, target, value) {
        let coll = this.getPropertyValue(target, propertyName);
        if (coll instanceof IgCollection) {
            for (let i = 0; i < coll.count; i++) {
                if (coll.item(i) && coll.item(i)._implementation) {
                    coll.item(i).___parent = null;
                }
            }
            coll.clear();
            let newArr = value;
            for (let i = 0; i < newArr.length; i++) {
                if (newArr[i] && newArr[i]._implementation) {
                    newArr[i].___parent = target;
                }
            }
            for (let i = 0; i < newArr.length; i++) {
                coll.add(newArr[i]);
            }
        }
        else if (Array.isArray(coll) || coll == null || coll == undefined) {
            if (coll) {
                for (let i = 0; i < coll.length; i++) {
                    if (coll[i] && coll[i]._implementation) {
                        coll[i].___parent = null;
                    }
                }
            }
            let newArr = value;
            for (let i = 0; i < newArr.length; i++) {
                if (newArr[i] && newArr[i]._implementation) {
                    newArr[i].___parent = target;
                }
            }
            this.setPropertyValue(target, propertyName, propertyMetadata, value, coll, null);
        }
        else {
            if (coll.clear !== undefined) {
                if (coll.count && coll.item) {
                    for (let i = 0; i < coll.count; i++) {
                        if (coll.item(i) && coll.item(i)._implementation) {
                            coll.item(i).___parent = null;
                        }
                    }
                }
                coll.clear();
            }
            if (coll.add !== undefined) {
                let newArr = value;
                for (let i = 0; i < newArr.length; i++) {
                    if (newArr[i] && newArr[i]._implementation) {
                        newArr[i].___parent = target;
                    }
                }
                for (let i = 0; i < newArr.length; i++) {
                    coll.add(newArr[i]);
                }
            }
        }
    }
    onPendingRef(target, propertyName, propertyMetadata, sourceRef) {
    }
    setPropertyValue(target, propertyName, propertyMetadata, value, oldValue, sourceRef) {
        if (this._platform == "Igx" &&
            IgcComponentRendererContainerComponent.isEvent &&
            IgcComponentRendererContainerComponent.isEvent(target[propertyName])) {
            if (target["_" + propertyName + "Subscription"]) {
                target["_" + propertyName + "Subscription"]();
                target["_" + propertyName + "Subscription"] = null;
            }
            var fun = function (ev) {
                value(ev.sender, ev.args);
            };
            var sub = target[propertyName].subscribe(fun);
            target["_" + propertyName + "Subscription"] = sub;
            return;
        }
        if (this._platform == "Igc" &&
            target.emitEvent &&
            target.addEventListener) {
            if (propertyMetadata &&
                propertyMetadata.knownType == TypeDescriptionWellKnownType.EventRef) {
                //TODO: this needs to come from the metadata.
                if (propertyName.endsWith("Ocurred")) {
                    propertyName = propertyName.replace("Ocurred", "");
                }
                if (propertyName.toLowerCase() == "selectionchanged") {
                    propertyName = "selection";
                }
                var eventId = "igc" + TypeDescriptionMetadata.toPascal(propertyName);
                if (value) {
                    target.addEventListener(eventId, value);
                }
                else {
                    target.removeEventListener(eventId, oldValue);
                }
                return;
            }
        }
        if (oldValue && oldValue._implementation) {
            value.___parent = null;
        }
        if (value && value._implementation) {
            value.___parent = target;
        }
        target[propertyName] = value;
    }
    getPropertyValue(target, propertyName) {
        return target[propertyName];
    }
    clearContainer(container, context, continueActions) {
        if (this._platform === "Igc") {
            let crc = IgcComponentRendererContainerComponent.fromElement(container);
            crc.clearContainer(continueActions);
            return;
        }
        let crc = container;
        crc.clearContainer(continueActions);
    }
    getRootObject(container) {
        if (this._platform === "Igc") {
            let crc = IgcComponentRendererContainerComponent.fromElement(container);
            return crc.getRootObject();
        }
        let crc = container;
        return crc.getRootObject();
    }
    forPropertyValueItem(target, propertyName, forItem) {
        let coll = this.getPropertyValue(target, propertyName);
        if (coll instanceof IgCollection) {
            for (let i = 0; i < coll.count; i++) {
                forItem(coll.item(i));
            }
        }
        else if (Array.isArray(coll)) {
            for (let i = 0; i < coll.length; i++) {
                forItem(coll[i]);
            }
        }
        else {
            if (coll.clear !== undefined) {
                for (let i = 0; i < coll.count; i++) {
                    forItem(coll.item(i));
                }
            }
        }
    }
    clearCollection(target, propertyName, metadata) {
        let coll = this.getPropertyValue(target, propertyName);
        if (coll instanceof IgCollection) {
            for (let i = 0; i < coll.count; i++) {
                if (coll.item(i) && coll.item(i)._implementation) {
                    coll.item(i).___parent = null;
                }
            }
            coll.clear();
        }
        else if (Array.isArray(coll)) {
            for (let i = 0; i < coll.length; i++) {
                if (coll[i] && coll[i]._implementation) {
                    coll[i].___parent = null;
                }
            }
            this.setPropertyValue(target, propertyName, metadata, [], coll, null);
        }
        else {
            if (coll.clear !== undefined) {
                for (let i = 0; i < coll.count; i++) {
                    if (coll.item(i) && coll.item(i)._implementation) {
                        coll.item(i).___parent = null;
                    }
                }
                coll.clear();
            }
        }
    }
    addItemToCollection(propertyName, propertyMetadata, target, newIndex, item) {
        let coll = this.getPropertyValue(target, propertyName);
        if (item && item._implementation) {
            item.___parent = target;
        }
        if (coll instanceof IgCollection) {
            coll.insert(newIndex, item);
        }
        else if (Array.isArray(coll)) {
            let newArr = [];
            for (let i = 0; i < coll.length; i++) {
                newArr[i] = coll[i];
            }
            newArr.splice(newIndex, 0, item);
            this.setPropertyValue(target, propertyName, propertyMetadata, newArr, coll, null);
        }
        else {
            if (coll.insert !== undefined) {
                coll.insert(newIndex, item);
            }
        }
    }
    resetPropertyOnTarget(container, propertyName, propertyMetadata, target) {
        //TODO: anything we can do here? store default?
    }
    replaceItemInCollection(propertyName, propertyMetadata, target, newIndex, item) {
        let coll = this.getPropertyValue(target, propertyName);
        if (item && item._implementation) {
            item.___parent = target;
        }
        if (coll instanceof IgCollection) {
            let oldValue = coll.item(newIndex);
            if (oldValue && oldValue._implementation) {
                oldValue.___parent = null;
            }
            coll.item(newIndex, item);
        }
        else if (Array.isArray(coll)) {
            let newArr = [];
            for (let i = 0; i < coll.length; i++) {
                newArr[i] = coll[i];
            }
            let oldValue = newArr[newIndex];
            if (oldValue && oldValue._implementation) {
                oldValue.___parent = null;
            }
            newArr[newIndex] = item;
            this.setPropertyValue(target, propertyName, propertyMetadata, newArr, coll, null);
        }
        else {
            if (coll.item !== undefined) {
                let oldValue = coll.item(newIndex);
                if (oldValue && oldValue._implementation) {
                    oldValue.___parent = null;
                }
                coll.item(newIndex, item);
            }
        }
    }
    removeItemFromCollection(propertyName, propertyMetadata, target, oldIndex) {
        let coll = this.getPropertyValue(target, propertyName);
        if (coll instanceof IgCollection) {
            let oldValue = coll.item(oldIndex);
            if (oldValue && oldValue._implementation) {
                oldValue.___parent = null;
            }
            coll.removeAt(oldIndex);
        }
        else if (Array.isArray(coll)) {
            let newArr = [];
            for (let i = 0; i < coll.length; i++) {
                newArr[i] = coll[i];
            }
            let oldValue = newArr[oldIndex];
            if (oldValue && oldValue._implementation) {
                oldValue.___parent = null;
            }
            newArr.splice(oldIndex, 1);
            this.setPropertyValue(target, propertyName, propertyMetadata, newArr, coll, null);
        }
        else {
            if (coll.removeAt !== undefined) {
                let oldValue = coll.item(oldIndex);
                if (oldValue && oldValue._implementation) {
                    oldValue.___parent = null;
                }
                coll.removeAt(oldIndex);
            }
        }
    }
    replaceRootItem(container, type, context, continueActions) {
        let typeName = "Igc" + type + "Component";
        var meta = context.getMetadata(type, "__qualifiedNameTS");
        if (meta) {
            typeName = "Igc" + meta.specificExternalType + "Component";
        }
        if (TypeRegistrar.isRegistered(typeName)) {
            let t = TypeRegistrar.get(typeName);
            if (this._platform === "Igc") {
                let crc = IgcComponentRendererContainerComponent.fromElement(container);
                crc.replaceRootItem(t, continueActions);
                return;
            }
            let crc = container;
            crc.replaceRootItem(t, continueActions);
        }
        else {
            if (this._platform === "Igc") {
                let crc = IgcComponentRendererContainerComponent.fromElement(container);
                crc.clearContainer(continueActions);
                return;
            }
            let crc = container;
            crc.clearContainer(continueActions);
        }
    }
    removeRootItem(container, context, continueActions) {
        this.clearContainer(container, context, continueActions);
    }
    flushChanges(container) {
    }
}
