﻿/// <reference path="authentication.js"/>
/// <reference path="packageLoader.js"/>
/// <reference path="layout.js"/>
/// <reference path="gadgetPreference.js"/>

gadgetProxy = (function () {
    var gadgetProxyLookup = {};
    var gadgetLayerLookup = {};

    var sizeChangedCallBack = {};
    var leaveCallBack = {};
    var onBookmarkChangedCallBack = {};
    var currentBookMark = {};

    function createGadgetProxy(id) {
        if (!sizeChangedCallBack[id]) {
            sizeChangedCallBack[id] = [];
            var autoSizeElement = null;
            var autoFit = function (size) {
                if (autoSizeElement) {
                    for (var i = 0; i < autoSizeElement.length; i++) {
                        size = size || (gadgetLayerLookup[id] && gadgetLayerLookup[id].getSize) ? gadgetLayerLookup[id].getSize() : { width: "0", height: "0" };
                        var l = autoSizeElement[i].style["margin-left"] ? autoSizeElement[i].style["margin-left"].replace("px", "") / 1 : 0;
                        var r = autoSizeElement[i].style["margin-right"] ? autoSizeElement[i].style["margin-right"].replace("px", "") / 1 : 0;
                        var t = autoSizeElement[i].style["margin-top"] ? autoSizeElement[i].style["margin-top"].replace("px", "") / 1 : 0;
                        var b = autoSizeElement[i].style["margin-bottom"] ? autoSizeElement[i].style["margin-bottom"].replace("px", "") / 1 : 0;
                        size.width = size.width - l - r;
                        size.height = size.height - t - b;
                        if (size.width > 0 && size.height > 0) {
                            $(autoSizeElement[i]).width(size.width);
                            $(autoSizeElement[i]).height(size.height);
                        }
                    }
                }
            }
            sizeChangedCallBack[id].push(autoFit);
        }
        if (!leaveCallBack[id]) {
            leaveCallBack[id] = [];
        }
        if (!onBookmarkChangedCallBack[id]) {
            onBookmarkChangedCallBack[id] = [];
            currentBookMark[id] = "";
        }
        if (!gadgetProxyLookup[id]) {
            var gadget = packageLoader.getGadget(id);
            gadgetProxyLookup[id] = {
                connect: function (accesspoint, account, password) {
                    return auth.connectTo(accesspoint, account, password);
                },
                getContract: function (contractName) {
                    return auth.connectTo(gadget.application.replace(/\/$/g, '') + "/" + contractName);
                },
                params: gadget.params, //gadgetCollection[id].params || {},
                getSize: function () {
                    return (gadgetLayerLookup[id] && gadgetLayerLookup[id].getSize) ? gadgetLayerLookup[id].getSize() : { width: "0", height: "0" };
                },
                setExterior: function (config) {
                    gadget.setExterior(config);
                },
                onSizeChanged: function (callBack) {
                    if (!callBack)
                        return;
                    sizeChangedCallBack[id].push(callBack);
                    if (gadgetLayerLookup[id] && gadgetLayerLookup[id].getSize) {
                        callBack(gadgetLayerLookup[id].getSize());
                    }
                },
                onLeave: function (callBack) {
                    if (!callBack)
                        return;
                    leaveCallBack[id].push(callBack);
                },
                getPreference: function (callBack) {
                    gadgetPreference.getPreference(gadget.url, function (obj) { callBack(obj); });
                },
                setPreference: function (obj) {
                    gadgetPreference.setPreference(gadget.url, obj);
                },
                autofit: function (element) {
                    autoSizeElement = element ? $(element) : null;
                    //autoFit();
                    if(gadgetLayerLookup[id] && gadgetLayerLookup[id].getSize)
                    	autoFit();
                },
                onBookmarkChanged: function (callBack) {
                    if (callBack) {
                        onBookmarkChangedCallBack[id].push(callBack);
                        callBack(currentBookMark[id]);
                    }
                },
                setBookmark: function (bookmark) {
                    for (var i = 0; i < setBookmarkCallBack.length; i++) {
                        setBookmarkCallBack[i](bookmark);
                    }
                },
                getGroupGadgets: function () {
                    var groups = [];
                    $(gadget.getGroup()).each(function (index, item) {
                        createGadgetProxy(item.id);
                        groups.push(gadgetProxyLookup[item.id]);
                    });
                    return groups;
                }
            };
        }
    }

    //#region 處理window的關閉視窗
    $(function () {
        window.onbeforeunload = function () {
            var errorStatus = "";
            for (var id in leaveCallBack) {
                for (var i = 0; i < leaveCallBack[id].length; i++) {
                    var s = leaveCallBack[id][i]();
                    if (s) {
                        errorStatus += "\n" + packageLoader.getGadget(id).title + ":" + s;
                    }
                }
            }
            if (errorStatus == "") return;
            else return ("關閉視窗可能導致下列小工具發生錯誤：" + errorStatus);
        }
    });
    //#endregion
    return {
        activeGadget: function (id) {
            createGadgetProxy(id);
            if (!gadgetLayerLookup[id]) {
                var layer = layout.createNewLayer(
                    {
                        zindex: 1,
                        visible: false
                    });
                gadgetLayerLookup[id] = layer;

                var setBookmarkCallBack = [];
                layer.onSetBookmark = function (callBack) {
                    if (callBack)
                        setBookmarkCallBack.push(callBack);
                } 
                layer.loadBookmark = function (bookmark) {
                    currentBookMark[id] = bookmark;
                    for (var i = 0; i < onBookmarkChangedCallBack[id].length; i++) {
                        onBookmarkChangedCallBack[i](bookmark);
                    }
                }
                layer.onVisibleChanged(function () {
                    if (!layer.getVisible()) {
                        for (var i = 0; i < leaveCallBack[id].length; i++) {
                            leaveCallBack[id][i]();
                        }
                    }
                });
                layer.onSizeChanged(function (newSize) {
                    for (var i = 0; i < sizeChangedCallBack[id].length; i++) {
                        sizeChangedCallBack[id][i](newSize);
                    }
                });

                for (var i = 0; i < sizeChangedCallBack[id].length; i++) {
                    sizeChangedCallBack[id][i](layer.getSize());
                }
            }
            return gadgetLayerLookup[id];
        },
        getGadgetProxy: function (id) {
            return gadgetProxyLookup[id];
        },
        checkLeave: function (id) {
            var result = "";
            for (var i = 0; i < leaveCallBack[id].length; i++) {
                var s = "" + leaveCallBack[id][i]();
                if (s != "")
                    return s;
            }
            return result;
        },
        removeGadgetLayer: function (id) {
            gadgetLayerLookup[id].remove();
            gadgetLayerLookup[id] = null;
            leaveCallBack[id] = [];
        }
    };
} ());
window.getGadgetProxy = function (id) { return gadgetProxy.getGadgetProxy(id); }
