﻿$.nmseo = {};

$.nmseo.Extensible = function(options) {
    options = options || {};
    this.initialize(options);
};

$.extend($.nmseo.Extensible, {
    initialize: function(options) {
        $.extend(this, options);
    }
});

$.nmseo.Extensible.extend = function(overrides) {
    var superClass = this;

    var subClass = function(options) {
        options = options || {};
        $.extend(this, subClass);
        this.initialize(options);
    };

    $.extend(subClass, superClass);
    $.extend(subClass, overrides);

    var p = function() { };
    p.prototype = superClass.prototype;
    subClass.prototype = new p();

    subClass.prototype.constructor = subClass;

    subClass.baseClass = superClass;

    return subClass;
};

$.nmseo.Control = $.nmseo.Extensible.extend({
    getContentObj: function() { },

    cacheResult: false,

    initialize: function(options) {
        this.container = options.container;
        $.nmseo.Control.baseClass.initialize.call(this, options);
    },

    render: function() {
        var obj;
        if (!this.cacheResult || !this.contentObj) {
            obj = this.getContentObj();
            if (this.cacheResult) {
                this.contentObj = obj;
            }
        }
        else {
            obj = this.contentObj;
        }
        if (typeof this.container == 'string') {
            this.container = $('#' + this.container);
        }
        $(this.container).html('').append(obj);
    }
});

$.nmseo.BindingSource = $.nmseo.Extensible.extend({
    clearHtml: true,

    getDataObj: function(data, index) {
        return data;
    },

    bindTo: function(options) { }
});

$.nmseo.AjaxBindingSource = $.nmseo.BindingSource.extend({
    initialize: function(options) {
        $.nmseo.AjaxBindingSource.baseClass.initialize.call(this, options); 

        this.url = options.url;
        this.method = options.method || 'post';
        this.contentType = options.contentType || 'application/json; charset=utf-8';
        this.data = options.data || {};
        this.isAsmx = (options.isAsmx == null) ? true : options.isAsmx;
        this.wrapper = options.wrapper;
        this.callback = options.callback || { scope: this, handler: function(data) { } };

        this.isPending = false;
    },

    prepareData: function(options) {
        var data = this.data;
        if (data) {
            if (this.isAsmx) {
                data = JSON.stringify(data);
            }
            return data;
        }
        else {
            return null;
        }
    },

    bindTo: function(options) {
        if (!this.isPending) {
            var target;
            target = options.target;
            if (typeof target == 'string') {
                target = $('#' + options.target);
            }
            var self = this;

            if (this.clearHtml) {
                target.html('');
            }

            var data = this.prepareData(options);

            this.isPending = true;

            $.ajax({
                url: this.url || options.url,
                type: this.method,
                data: data,
                contentType: this.contentType,
                dataType: 'json',
                cache: false,

                success: function(data, status) {
                    self.isPending = false;
                    self.callback.handler.call(self.callback.scope, data);
                    if (self.wrapper) {
                        data = data[self.wrapper];
                    }
                    if (data.length) {
                        if (data.length > 1) {
                            for (var i = 0; i < data.length; i++) {
                                var obj = self.getDataObj(data[i], i);
                                target.append(obj);
                            }
                        }
                        else if (data.length == 1) {
                            var obj = self.getDataObj(data[0], 0);
                            target.append(obj);
                        }
                    }
                    else {
                        var obj = self.getDataObj(data[0], 0);
                        target.append(obj);
                    }
                },

                error: function(xhr, status, ex) {
                    self.isPending = false;
                    target.append(xhr.responseText);
                }
            });
        }
    }
});

$.nmseo.PagedAjaxBindingSource = $.nmseo.AjaxBindingSource.extend({
    prepareData: function(options) {
        var data = this.data || {};
        var pageIndex = options.pageIndex || 1;
        var pageSize = options.pageSize || 20;
        data['pageIndex'] = pageIndex;
        data['pageSize'] = pageSize;
        if (this.isAsmx) {
            data = JSON.stringify(data);
        }
        return data;
    }
});

$.nmseo.SimpleBindingSource = $.nmseo.BindingSource.extend({
    initialize: function(options) {
        $.nmseo.SimpleBindingSource.baseClass.initialize.call(this, options); 
        if (options.data) {
            this.data = options.data;
        }
        else {
            this.data = new Array();
            this.initializeData(this.data);
        }
    },

    initializeData: function(data) {

    },

    bindTo: function(options) {
        var target = $('#' + options.target); 
        var self = this; 

        if (this.clearHtml) {
            target.html('');
        }

        $.each(this.data, function(index) {
            var obj = self.getDataObj(this, index); 
            target.append(obj); 
        });
    }
});

$.nmseo.Dialog = $.nmseo.Extensible.extend({
    getContentObj: function() { },

    cacheResult: true,

    isDialogWrapped: false,

    show: function() {
        if (!this.cacheResult || !this.contentObj) {
            this.contentObj = this.getContentObj();
        }

        if (this.isDialogWrapped) {
            this.contentObj.dialog('open');
        }
        else {
            this.isDialogWrapped = true;
            this.contentObj.dialog(this.dialogOptions);
        }
    },

    close: function(closing) {
        if (this.cacheResult) {
            if (!closing) {
                this.contentObj.dialog('close');
            }
        }
        else {
            this.contentObj.dialog('destroy').remove();
            this.isDialogWrapped = false;
            this.contentObj = null;
        }
    },

    initialize: function(options) {
        var self = this; 

        this.dialogOptions = options.dialogOptions || {};
        if (options.cacheResult != null) {
            this.cacheResult = options.cacheResult;
        }
        $.extend(this.dialogOptions, {
            bgiframe: true,
            close: function() {
                self.close(true);
            }
        });
    }
});

$.nmseo.GenericDialog = $.nmseo.Dialog.extend({
    initialize: function(options) {
        $.nmseo.GenericDialog.baseClass.initialize.call(this, options);
        this.getContentObj = options.getContentObj || function() { };
    }
});



$.create = function(options, parent) {
    if (!options || !options.tag) {
        return;
    }
    var element;
    if (options.tag.toLowerCase() == 'input') {
        element = '<input type="' + options.type + '" />';
    }
    else {
        element = '<' + options.tag + ' />';
    }
    element = $(element);
    if (parent) {
        parent.append(element);
    }
    if (typeof options.attributes == 'object') {
        element.attr(options.attributes);
    }
    if (typeof options.style == 'object') {
        element.css(options.style);
    }
    if (typeof options.className == 'string') {
        element.addClass(options.className);
    }
    if (typeof options.text == 'string') {
        element.html(options.text);
    }
    if (typeof options.value == 'string') {
        element.val(options.value);
    }
    if (options.callback) {
        options.callback(element);
    }
    if (options.children) {
        if (options.children.length) {
            for (var i = 0; i < options.children.length; i++) {
                var child = $.create(options.children[i], element);
            }
        }
        else {
            var child = $.create(options.children);
            element.append(child);
        }
    }
    return element;
};

$.nmseo.DoubleListBindingSource = $.nmseo.BindingSource.extend({
    initialize: function(options) {
        $.nmseo.DoubleListBindingSource.baseClass.initialize.call(this, options);
        this.data = options.data || new Array();
    },

    bindTo: function(options) {
        var self = this; 

        var parent = options.parent;
        var child = options.child;
        if (typeof parent == 'string') {
            parent = $('#' + parent);
        }
        if (typeof child == 'string') {
            child = $('#' + child);
        }
        var defaultItem = options.defaultItem;

        if (defaultItem) {
            parent.append(
                $.create({ tag: 'option', value: defaultItem.value, text: defaultItem.text })
            );
            child.append(
                $.create({ tag: 'option', value: defaultItem.value, text: defaultItem.text })
            );
        }
        $.each(this.data, function() {
            parent.append(
                $.create({ tag: 'option', value: this.value, text: this.text })
            );
        });
        parent.change(function() {
            
            child.html('');
            if (defaultItem) {
                child.append(
                    $.create({ tag: 'option', value: defaultItem.value, text: defaultItem.text })
                );
            }
            var value = parent.val();
            if (!defaultItem || value != defaultItem.value) {
                var subArr = $.grep(self.data, function(item) { return (item.value == value); });
                if (subArr.length > 0) {
                    var items = subArr[0].items;
                    $.each(items, function() {
                        child.append(
                            $.create({ tag: 'option', value: this.value, text: this.text })
                        );
                    });
                }
            }
        });
    }
});
