/// <reference path="../../../../Widgets/Wijmo/export/chartexport.ts" />
/// <reference path="c1json2.ts" />
/// <reference path="../../../../Widgets/Wijmo/External/declarations/jquery.d.ts" />

/*globals window, jQuery */
(function ($) {
    var win = window, jsonHiddenFieldIDSuffix = "__jsonserverstate", jsonHiddenFieldNameSuffix = "__jsonserverstate_ffcache", c1common = function () {
    };

    c1common.updateJsonHiddenField = function (controlID, jsonData) {
        var inputField = $("#" + controlID + jsonHiddenFieldIDSuffix);

        if (inputField.length > 0 && jsonData) {
            inputField.attr("value", jsonData);
        }
    };

    c1common.updateWebFormsInternals = function (controlID, jsonData) {
        var jsonHiddenFieldID = controlID + jsonHiddenFieldIDSuffix, jsonHiddenFieldName = controlID + jsonHiddenFieldNameSuffix, theFormPostCollection = win.__theFormPostCollection, theFormPostData = win.__theFormPostData, len, idx, replaceInHiddenField = function (original, name, newValue, encode) {
            var tmp = name + '=', start = 0, end, oldValue;

            if (original.substr(0, tmp.length) !== tmp) {
                tmp = '&' + tmp;
                start = original.indexOf(tmp);
            }

            if (start >= 0) {
                if (encode) {
                    newValue = win.WebForm_EncodeCallback(newValue);
                }
                start += tmp.length;
                end = original.indexOf('&', start);
                oldValue = original.substr(start, end - start);
                original = original.replace(tmp + oldValue, tmp + newValue);
            }

            return original;
        };

        if (theFormPostCollection) {
            len = theFormPostCollection.length;
            for (idx = 0; idx < len; idx++) {
                if (((theFormPostCollection)[idx].name === jsonHiddenFieldName) || ((theFormPostCollection)[idx].name === jsonHiddenFieldID)) {
                    (theFormPostCollection)[idx].value = jsonData;
                    break;
                }
            }
        }

        if (theFormPostData) {
            theFormPostData = replaceInHiddenField(theFormPostData, jsonHiddenFieldName, jsonData, true);
            win.__theFormPostData = replaceInHiddenField(theFormPostData, jsonHiddenFieldID, jsonData, true);
        }
    };

    c1common.registerRuntimeCSS = function (cssUrl) {
        if (!$("head").find("link[href='" + cssUrl + "']").length) {
            if ($(".wijmoBootstrapCss").length) {
                $(".wijmoBootstrapCss").before("<link href='" + cssUrl + "' rel='stylesheet' type='text/css' />");
            } else {
                $("head").append("<link href='" + cssUrl + "' rel='stylesheet' type='text/css' />");
            }
        }
    };

    c1common.removeFieldFromPostData = function (filedString) {
        var textareaVal = "&=" + window.WebForm_EncodeCallback(filedString);
        if (window.__theFormPostData.indexOf(textareaVal) > 0) {
            window.__theFormPostData = window.__theFormPostData.replace(textareaVal, "");
        }
    };

    c1common.JSON = {};
    c1common.JSON.stringify = function (obj) {
        return __JSONC1.stringify(obj, function (key, value) {
            var innerState = obj["innerStates"];

            // if the value is an jquery object, return it.
            if (value && value.jquery) {
                return;
            }
            if (key === "wijCSS" || key === "wijMobileCSS") {
                return;
            }
            if (typeof value === 'function') {
                if (innerState) {
                    if (innerState[key]) {
                        return { type: "fun", value: String(innerState[key]) };
                    }
                }
                return String(value);
            }
            return value;
        });
    };

    c1common.JSON.parse = function (str) {
        __JSONC1.parse(str, function (key, value) {
            if (typeof value === 'string') {
                if (/function()/.test(value)) {
                    return eval(value);
                }
                return value;
            }
            return value;
        });
    };

    c1common.htmlEncode = function (html) {
        var div = document.createElement("div"), textNode = document.createTextNode(html);
        div.appendChild(textNode);
        return div.innerHTML;
    };

    //c1common.htmlDecode = (code) => {
    //	var div = document.createElement("div");
    //	div.innerHTML = code;
    //	return div.innerHTML;
    //}
    win.c1common = c1common;

    $.fn.wijSaveState = function (widget, callback) {
        var self = this, wij, o, id;

        if (typeof (widget) === "string") {
            wij = self.data(widget);

            if (!wij) {
                wij = self.data("wijmo-" + widget); // The widgetFullName must be used since jQuery UI 1.10.
                if (!wij && $.camelCase) {
                    wij = self.data("wijmo" + $.camelCase(widget));
                }
            }
        } else if (typeof (widget) === "object") {
            wij = widget;
        }

        if (!wij) {
            return;
        }

        if ($.isFunction(wij[callback])) {
            if ((o = wij[callback].call(wij)) === null) {
                return;
            }
        }

        if (!o) {
            o = wij.options;
        }

        id = o.id || self.attr("id");
        c1common.updateJsonHiddenField(id, c1common.JSON.stringify(o));
    };

    /*
    Fix for memory leak when wijmo controls in updatepanel.
    */
    //for .net 4.0+
    if (window.Sys && window.Sys.Application && window.Sys.Application.disposeElement) {
        var originalDisposeElementFn = window.Sys.Application.disposeElement;

        // use an global array to store the dispose callback.
        $.disposeCallbackDatas = $.disposeCallbackDatas || {};

        // override the Sys.Application.disposeElement function
        window.Sys.Application.disposeElement = function (element, childNodes) {
            originalDisposeElementFn.apply(this, arguments); // call the original function first, so AJAX framework will be able to dispose nested AJAX controls properly (#90115).

            if (childNodes) {
                // destroy nested Wijmo widgets.
                $.each($.disposeCallbackDatas, function (id, widgetName) {
                    var widgetElement = $("#" + id, element);

                    if (widgetElement.length && widgetElement.data("wijmo-" + widgetName)) {
                        widgetElement[widgetName]("destroy");
                    }
                });
            }
        };
    }

    // for .net3.5
    if (window.Sys && window.Sys.WebForms && window.Sys.WebForms.PageRequestManager && window.Sys.WebForms.PageRequestManager.prototype._destroyTree) {
        var originalDestroyTree = window.Sys.WebForms.PageRequestManager.prototype._destroyTree;

        // use an global array to store the dispose callback.
        $.disposeCallbackDatas = $.disposeCallbackDatas || {};
        window.Sys.WebForms.PageRequestManager.prototype._destroyTree = function (element) {
            originalDestroyTree.apply(this, arguments);

            // destroy nested Wijmo widgets.
            $.each($.disposeCallbackDatas, function (id, widgetName) {
                var widgetElement = $("#" + id, element);

                if (widgetElement.length && widgetElement.data("wijmo-" + widgetName)) {
                    widgetElement[widgetName]("destroy");
                }
            });
        };
    }
}(jQuery));

// evaluates the code without strict functions in the call stack
window.c1common.nonStrictEval = function (code) {
    if (/__doPostBack/.test(code)) {
        // fix the strict mode issue in Chrome
        if (!window.event) {
            try  {
                window.event = {};
            } catch (ex) {
            }
        }
    }

    // these codes only works in FF.a
    // http://stackoverflow.com/questions/19357978/indirect-eval-call-in-strict-mode
    (1, eval)(code);
};

/*
fix for
"Uncaught  TypeError:  Cannot  read  property
'_notified'   of   null   "  exception  is thrown with  under  Google
Chrome((IE/FF works correctly)
under  ASP.NET 3.5 when an initially invisible
control put in UpdatePanel is made visible at postback.
*/
if (window.Sys && window.Sys.Browser) {
    window.Sys.Browser.WebKit = {};
    if (navigator.userAgent.indexOf('WebKit/') > -1) {
        window.Sys.Browser.agent = window.Sys.Browser.WebKit;
        window.Sys.Browser.version = parseFloat(navigator.userAgent.match(/WebKit\/(\d+(\.\d+)?)/)[1]);
        window.Sys.Browser.name = 'WebKit';
    }
}

window.c1chart = window.c1chart || {
    handleHintContents: function (content, dataObj, widget, getHintContent) {
        var str = "", getHintContentFromContents = function (data) {
            if (!data.type && data.data && data.data.type) {
                data = data.data;
            }
            return getHintContent(data);
        }, getContent = function (data) {
            var hintContent = getHintContentFromContents(data);
            if (!hintContent) {
                hintContent = widget._setDefaultTooltipText(data);
            }
            return hintContent;
        }, extendDataArgs = function (data) {
            var hintContent = getHintContentFromContents(data);
            if (hintContent) {
                $.extend(data, {
                    hintContent: hintContent
                });
            }
        };
        if (content === null || content === undefined) {
            if ($.isArray(dataObj)) {
                $.each(dataObj, function (i, data) {
                    str += getContent(data) + "\n";
                });
                return str;
            } else {
                return getContent(dataObj);
            }
        } else if ($.isFunction(content)) {
            if ($.isArray(dataObj)) {
                $.each(dataObj, function (i, data) {
                    extendDataArgs(data);
                });
            } else {
                extendDataArgs(dataObj);
            }
            return $.proxy(content, dataObj)();
        } else {
            return content;
        }
    },
    isInitChartExport: false,
    initChartExport: function () {
        if (!window.c1chart.isInitChartExport && wijmo && wijmo.exporter && wijmo.exporter.chartExport) {
            var chartExportPrototype = wijmo.exporter.chartExport.prototype, chartExportGetWidgetName = chartExportPrototype._getWidgetName;
            chartExportPrototype._getWidgetName = function () {
                return chartExportGetWidgetName.apply(this).replace("c1", "wij");
            };
            window.c1chart.isInitChartExport = true;
        }
    }
};
