﻿/// <reference name="MicrosoftAjax.js" />
/// <reference name="XMLControl.js" />
/// <reference name="Pager.js" />
/// <reference name="General.js" />

Type.registerNamespace("QuizArt.WebSites.PlayinStar.JS");

QuizArt.WebSites.PlayinStar.JS.SortableGrid = function(element) {
    QuizArt.WebSites.PlayinStar.JS.SortableGrid.initializeBase(this, [element]);
}

QuizArt.WebSites.PlayinStar.JS.SortableGrid.prototype = {
    // Data Members
    m_fields: null,
    m_pageSizeParameter: null,
    m_currentPageIndexParameter: null,
    m_sortFieldParameter: null,
    m_sortDirectionParameter: null,
    m_sortedFieldID: 0,
    m_sortFieldAscending: true,
    m_pageSize: 0,
    m_totalRecords: 0,
    m_operatorFolder: '',
    m_xslt: null,
    m_webMethodURL: null,
    m_refreshInterval: 0,

    m_maxPagesDisplay: 5,
    m_currentPageIndex: 0,
    m_displayFirstLast: false,

    m_totalRecordsXPath: null,
    m_duringRender: false,

    m_xmlControlWrapperCssClass: '',
    m_pagerControlWrapperCssClass: '',
    m_pagerCssClass: '',

    m_tableElement: null,
    m_pagerElement: null,

    m_displayPager: true,

    m_isRefreshCache: false,

    get_sortFieldAscending: function() {
        return m_sortFieldAscending;
    },
    set_sortFieldAscending: function(value) {
        if (value !== this.m_sortFieldAscending) {
            this.m_sortFieldAscending = value;
        }
    },
    get_displayPager: function() {
        /// <value>Must be set before initialization</value>
        return this.m_displayPager;
    },

    set_displayPager: function(value) {
        if (value !== this.m_displayPager) {
            this.m_displayPager = value;
        }
    },

    get_tableElement: function() {
        return this.m_tableElement;
    },

    get_pagerElement: function() {
        return this.m_pagerElement;
    },

    get_refreshInterval: function() {
        /// <value>The interval at which we'll reload the control.</value>
        return this.m_refreshInterval;
    },
    set_refreshInterval: function(value) {
        if (this.m_refreshInterval !== value) {
            if (value != 0 && value < 99) {
                throw Error.argumentOutOfRange('reloadInterval',
                    value, 'The reload interval must be 0 or over 100 milliseconds');
            }
            this.m_refreshInterval = value;
            this.raisePropertyChanged('refreshInterval');
        }
    },

    get_operatorFolder: function() { return this.m_operatorFolder; },
    set_operatorFolder: function(value) {
        if (value && value !== this.m_operatorFolder) {
            this.m_operatorFolder = value;
            this.raisePropertyChanged('operatorFolder');
        }
    },
    get_xmlControlWrapperCssClass: function() { return this.m_xmlControlWrapperCssClass; },
    set_xmlControlWrapperCssClass: function(value) {
        if (value && value !== this.m_xmlControlWrapperCssClass) {
            this.m_xmlControlWrapperCssClass = value;
            this.raisePropertyChanged('xmlControlWrapperCssClass');
        }
    },

    get_pagerControlWrapperCssClass: function() { return this.m_pagerControlWrapperCssClass; },
    set_pagerControlWrapperCssClass: function(value) {
        if (value && value !== this.m_pagerControlWrapperCssClass) {
            this.m_pagerControlWrapperCssClass = value;
            this.raisePropertyChanged('pagerControlWrapperCssClass');
        }
    },

    get_pagerCssClass: function() { return this.m_pagerCssClass; },
    set_pagerCssClass: function(value) {
        if (value && value !== this.m_pagerCssClass) {
            this.m_pagerCssClass = value;
            this.raisePropertyChanged('pagerCssClass');
        }
    },

    get_maxPagesDisplay: function() { return this.m_maxPagesDisplay; },
    set_maxPagesDisplay: function(value) {
        if (value && value != this.m_maxPagesDisplay) {
            this.m_maxPagesDisplay = value;
            this.raisePropertyChanged('maxPagesDisplay');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_currentPageIndex: function() { return this.m_currentPageIndex; },
    set_currentPageIndex: function(value) {
        if (value != null && value != this.m_currentPageIndex) {
            this.m_currentPageIndex = value;
            this.raisePropertyChanged('currentPageIndex');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_displayFirstAndLast: function() { return this.m_displayFirstLast; },
    set_displayFirstAndLast: function(value) {
        if (value && value !== this.m_displayFirstLast) {
            this.m_displayFirstLast = value;
            this.raisePropertyChanged('displayFirstAndLast');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_fields: function() { return this.m_fields; },
    set_fields: function(value) {
        if (value && value !== this.m_fields) {
            this.m_fields = value;
            this.raisePropertyChanged('fields');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_pageSizeParameter: function() { return this.m_pageSizeParameter; },
    set_pageSizeParameter: function(value) {
        if (value && value !== this.m_pageSizeParameter) {
            this.m_pageSizeParameter = value;
            this.raisePropertyChanged('pageSizeParameter');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_currentPageIndexParameter: function() { return this.m_currentPageIndexParameter; },
    set_currentPageIndexParameter: function(value) {
        if (value && value !== this.m_currentPageIndex) {
            this.m_currentPageIndexParameter = value;
            this.raisePropertyChanged('currentPageIndexParameter');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_sortFieldParameter: function() { return this.m_sortFieldParameter; },
    set_sortFieldParameter: function(value) {
        if (value && value !== this.m_sortFieldParameter) {
            this.m_sortFieldParameter = value;
            this.raisePropertyChanged('sortFieldParameter');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_sortFieldAscending: function() { return this.m_sortDirectionParameter; },
    set_sortFieldAscending: function(value) {
        if (value !== this.m_sortFieldAscending) {
            this.m_sortFieldAscending = value;
            this.raisePropertyChanged('sortFieldAscending');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_sortDirectionParameter: function() { return this.m_sortDirectionParameter; },
    set_sortDirectionParameter: function(value) {
        if (value && value !== this.m_sortDirectionParameter) {
            this.m_sortDirectionParameter = value;
            this.raisePropertyChanged('sortDirectionParameter');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_sortedFieldID: function() { return this.m_sortedFieldID; },
    set_sortedFieldID: function(value) {
        if (value && value !== this.m_sortedFieldID) {
            this.m_sortedFieldID = value;
            this.raisePropertyChanged('sortedFieldID');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_pageSize: function() { return this.m_pageSize; },
    set_pageSize: function(value) {
        if (value && value !== this.m_pageSize) {
            this.m_pageSize = value;
            this.raisePropertyChanged('pageSize');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_totalRecords: function() { return this.m_totalRecords; },
    set_totalRecords: function(value) {
        if (value && value !== this.m_totalRecords) {
            this.m_totalRecords = value;
            this.raisePropertyChanged('totalRecords');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_isRefreshCache: function() { return this.m_isRefreshCache; },
    set_isRefreshCache: function(value) {
        if (value !== this.m_isRefreshCache) {
            this.m_isRefreshCache = value;
            this.raisePropertyChanged('isRefreshCache');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_xslt: function() {
        /// <value>Gets or sets the XSLT for the control.</value>
        return this.m_xslt;
    },
    set_xslt: function(value) {
        if (this.m_xslt !== value) {
            this.m_xslt = value;
            this.raisePropertyChanged('xslt');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    get_webMethodURL: function() {
        /// <value>
        /// Gets or sets a web method that supports paging and sorting.
        /// The web method must include the "?" character at the end if it has no other parameters, 
        /// or the "&" character if it has a at least one parameter.
        /// </value>
        return this.m_webMethodURL;
    },
    set_webMethodURL: function(value) {
        if (this.m_webMethodURL !== value) {
            this.m_webMethodURL = value;
            this.raisePropertyChanged('webMethodURL');
        }
        this.m_currentPageIndex = 0;

        if (this.canRender()) {
            this._render();
        }
    },

    get_totalRecordsXPath: function() {
        /// <value>
        /// Gets or sets the XPath to the total number of records field on the result
        /// XML that was received from the XML URL.
        /// </value>
        return this.m_totalRecordsXPath;
    },
    set_totalRecordsXPath: function(value) {
        if (this.m_totalRecordsXPath !== value) {
            this.m_totalRecordsXPath = value;
            this.raisePropertyChanged('totalRecordsXPath');
        }

        if (this.canRender()) {
            this._render();
        }
    },

    add_afterInitialize: function(handler) {
        /// <value>Bind and unbind to the after initialize event.</value>
        this.get_events().addHandler('afterInitialize', handler);
    },
    remove_afterInitialize: function(handler) {
        this.get_events().removeHandler('afterInitialize', handler);
    },

    add_error: function(handler) {
        /// <value> Bind and unbind to the error event. </value>
        this.get_events().addHandler('error', handler);
    },
    remove_error: function(handler) {
        this.get_events().removeHandler('afterInitialize', handler);
    },

    add_render: function(handler) {
        this.get_events().addHandler('render', handler);
    },
    remove_render: function(handler) {
        this.get_events().removeHandler('render', handler);
    },

    add_prerender: function(handler) {
        this.get_events().addHandler('prerender', handler);
    },
    remove_prerender: function(handler) {
        this.get_events().removeHandler('prerender', handler);
    },

    updateFieldAndDirection: function(newFieldID, newDirection) {
        var needUpdate = false;

        if (newFieldID !== this.m_sortedFieldID) {
            needUpdate = true;
            this.m_sortedFieldID = newFieldID;
            this.raisePropertyChanged('sortedFieldID');
        }

        if (newDirection !== this.m_sortFieldAscending) {
            needUpdate = true;
            this.m_sortFieldAscending = newDirection;
            this.raisePropertyChanged('sortFieldAscending');
        }

        if (needUpdate && this.canRender()) {
            this._render();
        }
    },

    _renderTitlebar: function() {
        var control = this.get_element();
        var xmlControl = document.getElementById(control.id + '_div');

        // Create the title row
        var titleRow = document.createElement('tr');

        // For each field add a column to the title row
        for (var fieldIndex = 0; fieldIndex < this.m_fields.length; fieldIndex++) {
            var newColumn = document.createElement('th');
            var sortImgColumn = document.createElement('th');
            if (navigator.appName.indexOf("Microsoft Internet") != -1) {
                sortImgColumn.style.width = '1%';
            }
            else {
                sortImgColumn.style.width = '10px';
            }
            sortImgColumn.style.padding = '0px 0px 0px 0px';

            if (this.m_fields[fieldIndex].width != undefined) {
                newColumn.style.width = this.m_fields[fieldIndex].width;
                sortImgColumn.style.width = this.m_fields[fieldIndex].width;
            }

            if (this.m_fields[fieldIndex].id == -1) {
                newColumn.innerHTML = '<a href="javascript:void(0)">' + this.m_fields[fieldIndex].headline + '</a>';
            }
            else if (this.m_fields[fieldIndex].id == this.m_sortedFieldID) {
                var sortImageName;
                if (this.m_sortFieldAscending) {
                    sortImageName = this.m_operatorFolder + 'images/icons/sortUp.gif';
                }
                else {
                    sortImageName = this.m_operatorFolder + 'images/icons/sortDwn.gif';
                }

                newColumn.innerHTML = String.format('<a href="javascript:QuizArt.WebSites.PlayinStar.JS.SortableGrid.SortByField(&#39{0}&#39, {1}, {2});"> {3}</a>',
                        control.id, this.m_fields[fieldIndex].id, !this.m_sortFieldAscending, this.m_fields[fieldIndex].headline,
                        sortImageName);
                sortImgColumn.innerHTML = String.format('<a href="javascript:QuizArt.WebSites.PlayinStar.JS.SortableGrid.SortByField(&#39{0}&#39, {1}, {2});"><img src="{4}" alt="" /></a>',
                        control.id, this.m_fields[fieldIndex].id, !this.m_sortFieldAscending, this.m_fields[fieldIndex].headline,
                        sortImageName);

                // Adds the sort image to the title bar        
                titleRow.appendChild(sortImgColumn);
            }
            else {
                newColumn.innerHTML = String.format('<a href="javascript:QuizArt.WebSites.PlayinStar.JS.SortableGrid.SortByField(&#39{0}&#39, {1}, {2});">' +
                        '{3}</a>',
                        control.id, this.m_fields[fieldIndex].id, true, this.m_fields[fieldIndex].headline);
                sortImgColumn.innerHTML = String.format('<a href="javascript:QuizArt.WebSites.PlayinStar.JS.SortableGrid.SortByField(&#39{0}&#39, {1}, {2});">' +
                        '<img src="' + this.m_operatorFolder + 'images/icons/sortNone.gif" alt="" /></a>',
                        control.id, this.m_fields[fieldIndex].id, true, this.m_fields[fieldIndex].headline);

                // Adds the sort image to the title bar        
                titleRow.appendChild(sortImgColumn);
            }

            // Add the column to the title row
            titleRow.appendChild(newColumn);
        }

        var thead = document.createElement('thead');
        thead.appendChild(titleRow);

        var controlTable = xmlControl.firstChild;

        // This should be the table
        if (controlTable.firstChild != null) {
            controlTable.insertBefore(thead, controlTable.firstChild);
        }
        else {
            controlTable.appendChild(thead);
        }
    },

    _setTotalRecords: function(sender, xml) {
        if (xml) {
            var control = this.get_element();

            if (this.m_totalRecordsXPath !== null && this.m_totalRecords !== '') {
                var totalRecordsNode;
                if (!xml.evaluate) {
                    totalRecordsNode = parseInt(xml.selectSingleNode(this.m_totalRecordsXPath).text);
                }
                else {
                    var totalRecordsNode =
                    xml.evaluate(this.m_totalRecordsXPath, xml, null, XPathResult.NUMBER_TYPE, null).numberValue;
                }
                this.m_totalRecords = totalRecordsNode;

                // Set the Pager Control with all the parameters is needs
                var pagerControl = $find(control.id + '_pager');
                if (pagerControl != null) {
                    pagerControl.set_maxPagesDisplay(this.m_maxPagesDisplay);
                    pagerControl.set_totalPages(Math.ceil(this.m_totalRecords / this.m_pageSize));
                    pagerControl.set_currentPageIndex(this.m_currentPageIndex);
                }
            }
        }
    },

    canRender: function() {
        return (this.m_fields != null) && (this.m_sortDirectionParameter != null) &&
               (this.m_sortFieldParameter != null) && (this.m_sortFieldAscending != null) &&
               (this.m_sortedFieldID != null) && (this.m_xslt != null) && (this.m_webMethodURL != null) &&
               !this.get_isUpdating() && (!this.m_displayPager || (
                    (this.m_currentPageIndexParameter != null) &&
                    (this.m_pageSizeParameter != null) &&
                    (this.m_pageSize != null) &&
                    (this.m_totalRecords != null)));
    },

    _render: function() {
        var control = this.get_element();
        if (control == null) {
            return;
        }

        var completeWebMethodURL;

        // Create the complete web method call (If no paging is requested then we don't pass it at all)
        if (this.m_pageSizeParameter === '' || this.m_currentPageIndex === '') {
            completeWebMethodURL = String.format('{0}{1}={2}&{3}={4}',
                this.m_webMethodURL,
                this.m_sortDirectionParameter, this.m_sortFieldAscending,
                this.m_sortFieldParameter, this.m_sortedFieldID);
        }
        else {
            completeWebMethodURL = String.format('{0}{1}={2}&{3}={4}&{5}={6}&{7}={8}',
                this.m_webMethodURL,
                this.m_sortDirectionParameter, this.m_sortFieldAscending,
                this.m_currentPageIndexParameter, this.m_currentPageIndex,
                this.m_pageSizeParameter, this.m_pageSize,
                this.m_sortFieldParameter, this.m_sortedFieldID);
        }

        // Set the XML Control with all the paramters it needs (XmlURL and XSLT URL)
        var xmlControl = $find(control.id + '_div');
        xmlControl.set_isRefreshCache(this.m_isRefreshCache);
        xmlControl.set_xsltUrl(this.m_xslt);
        xmlControl.set_xmlUrl(completeWebMethodURL);
    },

    pageIndexChangedHandler: function(sender, newPageIndex) {
        this.set_currentPageIndex(newPageIndex);
    },

    initialize: function() {
        QuizArt.WebSites.PlayinStar.JS.SortableGrid.callBaseMethod(this, 'initialize');

        var control = this.get_element();

        // Create a table element under the given control and attach the XML Control to it
        this.m_tableElement = document.createElement('div');
        this.m_tableElement.className = this.m_xmlControlWrapperCssClass;
        this.m_tableElement.id = control.id + '_div';
        control.appendChild(this.m_tableElement);

        var xmlControlEvents = new Object();
        if (this.get_events().getHandler('error') != null) {
            xmlControlEvents.error = this.get_events().getHandler('error');
        }
        if (this.get_events().getHandler('render') != null) {
            xmlControlEvents.render = this.get_events().getHandler('render');
        }
        if (this.get_events().getHandler('prerender') != null) {
            xmlControlEvents.prerender = this.get_events().getHandler('prerender');
        }
        var xmlControl = $create(QuizArt.WebSites.PlayinStar.JS.XMLControl, null, xmlControlEvents, null, this.m_tableElement);

        xmlControl.set_reloadInterval(this.m_refreshInterval);

        // Add a handler to the after render event
        xmlControl.add_render(Function.createDelegate(this, this._renderTitlebar));
        xmlControl.add_xmlLoaded(Function.createDelegate(this, this._setTotalRecords));

        // Create a div element under the given control and attach the Pager control to it
        if (this.m_displayPager) {
            this.m_pagerElement = document.createElement('div');
            this.m_pagerElement.setAttribute('class', this.m_pagerControlWrapperCssClass);
            control.appendChild(this.m_pagerElement);

            var pagerControlElement = document.createElement('span');
            pagerControlElement.id = control.id + '_pager';
            this.m_pagerElement.appendChild(pagerControlElement);

            var pagerProps = {
                cssClass: this.m_pagerCssClass,
                operatorFolder: this.m_operatorFolder 
            };
            var pagerEvents = {
                pageIndexChanged: Function.createDelegate(this, this.pageIndexChangedHandler)
            };

            var pagerControl = $create(QuizArt.WebSites.PlayinStar.JS.Pager, pagerProps, pagerEvents, null, pagerControlElement);
        }

        var afterInitializeHandler = this.get_events().getHandler('afterInitialize');
        if (afterInitializeHandler) {
            afterInitializeHandler(this, Sys.EventArgs.Empty);
        }

        if (this.canRender()) {
            this._render();
        }
    },

    dispose: function() {
        if (!this.m_isFirstRender) {
            var control = this.get_element();
            var xmlControl = $find(control.id + '_div');
            if (xmlControl != null) {
                xmlControl.dispose();
            }

            var pagerControl = $find(control.id + '_pager');
            if (pagerControl != null) {
                pagerControl.dispose();
            }
        }

        QuizArt.WebSites.PlayinStar.JS.SortableGrid.callBaseMethod(this, 'dispose');
    }
}
QuizArt.WebSites.PlayinStar.JS.SortableGrid.registerClass('QuizArt.WebSites.PlayinStar.JS.SortableGrid', Sys.UI.Control);

QuizArt.WebSites.PlayinStar.JS.SortableGrid.SortByField = function(elementID, sortField, sortAscending) {
    var gridControl = $find(elementID);

    if (gridControl) {
        gridControl.updateFieldAndDirection(sortField, sortAscending);
    }
}

if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

