/**
* Script contains all functions for dealing with numbers. 
* Includes localized formatting as well as validation methods. 
*
* DO NOT CHANGE UNLESS YOU KNOW WHAT YOU ARE DOING!
*/

var NwlExt = {
    version : "1.0.0",
    extSupport: "3.1.0"
};

/*
 * Sets a default header on all AJAX request to include the NWL header.
 */
Ext.Ajax.defaultHeaders = { 'nwl-ajax': 'NwlAjaxianData' };


Ext.override(Ext.form.HtmlEditor, {
    // private
    defaultValue: (Ext.isOpera || Ext.isIE6) ? '&#160;' : '&#8203;',

    cleanHtml: function(html) {
    
        // START FIX
        /*
         *  Temporary fix for Ext 3.2 and lower to remove "?" from empty HTML editors.
         *  See: http://www.extjs.com/forum/showthread.php?73293-FIXED-87-3.0RC3-HTMLEditor-prepends-to-message 
         */
        var dv = this.defaultValue;
    
        html = String(html);
        
        if (Ext.isWebKit) { // strip safari nonsense
            html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
        }
        
        // Strip default character.
        html = html.replace("\u200B", "")

        // END FIX
        
        // START FIX - Remove host name from inserted image.
        var hostName = new RegExp(window.location.protocol + "\/\/" +  window.location.hostname, "g");
        html = html.replace(hostName, "");
        // END FIX
        
        // remove microsoft jibberish using regex jibberish
        var removals = [/&nbsp;/ig, /[\r\n]/g, /<(xml)[^>]*>.*?<\/\1>/ig, /<\/?(meta|object)[^>]*>/ig, /<\/?[A-Z0-9]*:[A-Z]*[^>]*>/ig,
        /(lang|type|name|title|clear)=\"[^\"]*\"/ig, /<![\[-].*?-*>/g, /MsoNormal/g, /<\\?\?xml[^>]*>/g, 
        /<\/?v:[^>]*>/g, /<\/?o:[^>]*>/g, /<\/?st1:[^>]*>/g,
        /<!--(.*)-->/g, /<!--(.*)>/g, /<!(.*)-->/g, /<\\?\?xml[^>]*>/g, /<\/?v:[^>]*>/g, /<\/?o:[^>]*>/g, /<\/?st1:[^>]*>/g,        
        /lang=\"[^\"]*\"/g, /lang=\'[^\"]*\'/g, /type=\"[^\"]*\"/g, /type=\'[^\"]*\'/g,
        /name=\"[^\"]*\"/g, /name=\'[^\"]*\'/g, / clear=\"all\"/g, /title=\"[^\"]*\"/g];

        Ext.each(removals, function(s) {
          html = html.replace(s, "");
        });

        return html;
    }
});


/**
 * NWL Ext implementation of the JSON Reader.
 */
NwlExt.JsonReader = function(meta, recordType){
    
    NwlExt.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
};

Ext.extend(NwlExt.JsonReader, Ext.data.JsonReader, {
    read : function(response){
        // Unwrap JSON to strip out the NWL header.
        var json = DataTransfer.unwrapJson(response.responseText);
        var o = Ext.decode(json);
        if(!o) {
            throw {message: 'JsonReader.read: Json object not found'};
        }
        
        // Pass data to read records.
        var results = this.readRecords(o.data);
        
        results.hasPrevPage = o.hasPrevPage !== 'undefined' ? o.data.hasPrevPage : false;
        results.hasNextPage = o.hasNextPage !== 'undefined' ? o.data.hasNextPage : false;
        results.hasPrevSet = o.hasPrevSet !== 'undefined' ? o.data.hasPrevSet : false;
        results.hasNextSet = o.hasNextSet !== 'undefined' ? o.data.hasNextSet : false;
        results.pagesAvailable = o.pagesAvailable !== 'undefined' ? o.data.pagesAvailable : 0;
        results.setNumber = o.setNumber !== 'undefined' ? o.data.setNumber : 0;
        results.currentPage = o.currentPage !== 'undefined' ? o.data.currentPage : 0;
        
        return results;
        
    },
    readResponse : function(action, response) {
        // Unwrap JSON to strip out the NWL header.
        if (response.responseText !== undefined) {
            response.responseText = DataTransfer.unwrapJson(response.responseText);
        };
        return NwlExt.JsonReader.superclass.readResponse.call(this, action, response);
    }
});

/**
 * NWL JsonStore. Uses custom NWL JsonReader and adds paging parameters. 
 */
NwlExt.JsonStore = Ext.extend(Ext.data.Store, {
    
    pageSize : 10,
    pagingSetSize : 5,
    currentPage: 1,
    hasPrevPage : false,
    hasNextPage : false,
    hasPrevSet  : false,
    hasNextSet  : false,
    setNumber  : 0,
    pagesAvailable : 0,
    
    constructor: function(config){
        NwlExt.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
            reader: new NwlExt.JsonReader(config)
        }));
    },
    
    load : function(options) {
        var searchParameters = {MAX_PAGE_ROWS:this.pageSize, setSize:this.pagingSetSize};
        options.params = options.params || {};
        if (!options.params['currentPage']) {
        	if (this.currentPage > 0) {
        		Ext.apply(searchParameters, {currentPage: this.currentPage});
        	} else {
        		Ext.apply(searchParameters, {currentPage: 1});
        	}
        }
        Ext.apply(options.params, searchParameters);
        return NwlExt.JsonStore.superclass.load.call(this, options);
    },
    
    loadRecords : function(o, options, success){
        
        this.hasPrevPage = o.hasPrevPage !== 'undefined' ? o.hasPrevPage : false;
        this.hasNextPage = o.hasNextPage !== 'undefined' ? o.hasNextPage : false;
        this.hasPrevSet = o.hasPrevSet !== 'undefined' ? o.hasPrevSet : false;
        this.hasNextSet = o.hasNextSet !== 'undefined' ? o.hasNextSet : false;
        this.setNumber = o.setNumber !== 'undefined' ? o.setNumber : false;
        this.pagesAvailable = o.pagesAvailable !== 'undefined' ? o.pagesAvailable : 0;
        this.currentPage = o.currentPage !== 'undefined' ? o.currentPage : 1;
        
        return NwlExt.JsonStore.superclass.loadRecords.call(this, o, options, success);
        
    },
    
    setPageSize : function (value){
        this.pageSize = value;
    },
    
    setPagingSetSize : function (value){
        this.pagingSetSize = value;
    },
    
    setCurrentPage : function (value){
        this.currentPage = value;
    }
    
});

/**
* NWL Paging Toolbar
*/
(function() {

    var T = Ext.Toolbar;

    NwlExt.PagingToolbar = Ext.extend(Ext.Toolbar, {
        
        beforePageText : 'Page:',
        firstText : 'First Page',
        prevText : 'Previous Page',
        nextText : 'Next Page',
        lastText : 'Last Page',
        
        initComponent : function(){   
        
            var hasPrevPage=false;
            var hasNextPage=false;
            var hasPrevSet=false;
            var hasNextSet=false;
            var setSize=1;
            var setNumber=1;
            var pagesAvailable=0;
        
            this.prevSet = new T.Button({
                tooltip: this.prevSetText,
                overflowText: this.prevSetText,
                iconCls: 'x-tbar-page-first',
                disabled: true,
                handler: this.goPreviousSet,
                scope: this
            })
            
            this.prevPage = new T.Button({
                tooltip: this.prevText,
                overflowText: this.prevPageText,
                iconCls: 'x-tbar-page-prev',
                disabled: true,
                handler: this.goPreviousPage,
                scope: this
            })
            
            this.nextPage = new T.Button({
                tooltip: this.nextPageText,
                overflowText: this.nextPageText,
                iconCls: 'x-tbar-page-next',
                disabled: true,
                handler: this.goNextPage,
                scope: this
            })
            
            this.nextSet = new T.Button({
                tooltip: this.nextSetText,
                overflowText: this.nextSetText,
                iconCls: 'x-tbar-page-last',
                disabled: true,
                handler: this.goNextSet,
                scope: this
            });


            delete this.buttons;
            
            Ext.PagingToolbar.superclass.initComponent.call(this);
            
            this.addEvents(
                'beforechange'
            );
            
            this.doCreateToolBar();
            
            
        },

        
        doCreateToolBar : function(){
            
            this.prevSet.setDisabled(!this.store.hasPrevSet);
            this.prevPage.setDisabled(!this.store.hasPrevPage);
            this.nextPage.setDisabled(!this.store.hasNextPage);
            this.nextSet.setDisabled(!this.store.hasNextSet);
            this.pagesAvailable = this.store.pagesAvailable;
            this.setNumber = this.store.setNumber;
            this.pagingSetSize = this.store.setSize;
            
            this.add('-', this.prevSet);
            this.addButton(this.prevPage);
            
            this.add(this.beforePageText);
            
            for (var idx=1; idx <= this.pagesAvailable; idx=idx+1) {
                var buttonPageNumber = ((this.setNumber-1)*this.pagingSetSize)+idx;
                var newButton = new T.Button({
                    id: 'pagingButton' +  idx,
                    tooltip: buttonPageNumber,
                    overflowText: buttonPageNumber,                    
                    disabled: false,
                    handler: this.onHandlePageButton,
                    scope: this,
                    pressed: true,
                    text : buttonPageNumber,
                    currentPage : buttonPageNumber
                })
                if (this.store.currentPage == buttonPageNumber) {
                    newButton.disabled=true;
                }
                                    
                this.add('-', newButton);
            }
            
            this.addButton(this.nextPage);
            this.addButton(this.nextSet);
            
        },
        
        onHandlePageButton : function (button, event) {
            this.doLoad(button.currentPage);
        },
        
        getParams : function(){
            return this.paramNames || this.store.paramNames;
        },
        
        doLoad : function(currentPage){
            this.store.currentPage = currentPage;
            var o = this.store.lastOptions.params;
            o.currentPage = currentPage;
            if(this.fireEvent('beforechange', this, o) !== false){
                this.store.load({params:o});
            }
        },
        
        goPreviousSet : function(){
            this.doLoad((this.setNumber-1)*this.pagingSetSize);
        },

        goPreviousPage : function(){
            this.doLoad(this.store.currentPage-1);
        },
        
        goNextPage : function(){
            this.doLoad(this.store.currentPage+1);
        },

        goNextSet : function(){
            this.doLoad((this.setNumber*this.pagingSetSize)+1);
        },
        
        onDestroy : function(){
            Ext.PagingToolbar.superclass.onDestroy.call(this);
        }
    });
})();

/**
 * Ext grid with paging embedded.
 */
NwlExt.PagingGridPanel = Ext.extend(Ext.grid.GridPanel, {
    
    loggingEnabled : false,
    idsAsString : "",
    selectedIds : new Array(0),
    
    constructor: function(config){
        NwlExt.PagingGridPanel.superclass.constructor.call(this, Ext.apply(config, {
            bbar: [{hidden : true}]
        }));
        this.store.on('load', this.doSetupPaging,  this);
    },
    
    initComponent : function(){
        NwlExt.PagingGridPanel.superclass.initComponent.call(this);
        if (this.idsAsString !== "") {
            var idArray = this.idsAsString.split(',');
            this.addIds(idArray);
        }
    },
    
    doSetupPaging : function(store, r, options){
        
        // Clear existing paging bar.
        this.bbar.update('');
        
        // Create new bar.
        var pagingToolBar = new NwlExt.PagingToolbar({
            pageSize: this.store.pageSize,
            store: this.store,
            displayInfo: true
        });

        // render bar
        pagingToolBar.render(this.bbar);

        this.bbar.hidden = false;
        
    },
    
    
    addId : function(id) {
        this.addIds([id]);
    },
    
    addIds : function(idArray) {
        
        this.log("Adding array:[" + idArray + "]");

        if (!(idArray instanceof Array)) {
            return;
        }

        for ( var idxToAdd = 0; idxToAdd < idArray.length; idxToAdd = idxToAdd + 1) {
            var found = false;
            var id = idArray[idxToAdd];
            for ( var existingIdx = 0; existingIdx < this.selectedIds.length; existingIdx = existingIdx + 1) {
                if (id == this.selectedIds[existingIdx]) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                this.selectedIds[this.selectedIds.length] = id;
            }
        }
        
        this.log("Selected Ids:[" + this.selectedIds + "]");

    },
    
    removeId : function(id) {
        this.removeIds([id]);
    },

    removeIds : function(idArray) {
        
        this.log("Removing array:[" + idArray + "]");
        
        if (!(idArray instanceof Array)) {
            return;
        }

        for ( var idxToAdd = 0; idxToAdd < idArray.length; idxToAdd = idxToAdd + 1) {
            var id = idArray[idxToAdd];
            for ( var existingIdx = 0; existingIdx < this.selectedIds.length; existingIdx = existingIdx + 1) {
                if (id == this.selectedIds[existingIdx]) {
                    this.selectedIds.splice(existingIdx, 1);
                    break;
                }
            }
        }
        
        this.log("Selected Ids:[" + this.selectedIds + "]");
        
    },

    isIdSelected : function(id) {
        this.log("Checking if id selected. Id:[" + id + "], Array:[" + this.selectedIds + "]");
        for ( var idx = 0; idx < this.selectedIds.length; idx = idx + 1) {
            this.log("Checking if id selected. Id:[" + id + "], Array Value:[" + this.selectedIds[idx] + "]");
            if (id == this.selectedIds[idx]) {
                return true;
            }
        }
        return false;
    },
    
    getSelectedIdsAsString : function() {
        return this.selectedIds.join(",");
    },
    
    clearSelectedIds : function() {
        this.selectedIds = new Array(0);
    },
    
    getSize : function() {
        return this.selectedIds.length;
    },
    
    hasIdsSelected : function() {
        return this.selectedIds.length > 0;
    },
    
    log : function(msg) {
        if (this.loggingEnabled === true) {
            console.log(msg);
        }
    }
    
});