/*
---

name: WA.Util

description: This is a utility class that we can add useful reusable
             methods to for use on any page. Good place to add global functions
             from legacy application code.

requires: WA

provides: IE checking, IE z order fixing, and more...

...
*/
WA = new Class({});
WA.Util = new Class({
    Extends: WA,
    initialize: function(options){
        // zero if non-IE, otherwise will be numeric version (6,7,8,etc);
        this.IE = /*@cc_on Number(String(@_jscript_version).split('.')[1]) + @*/0;
    },
    testWA: function() {
        this.log('wa.js is loaded');
    },
    validator: function() {
        if( this._validator === undefined ) {
            this._validator = new FormValidation();
        }
        return this._validator;
    },
    fixZOrder: function() {
        var z = 9998;
        var divs = $$('#webAssign #top div');
        for( var i = 0; i < divs.length; i++ ) {
            // only set a z-index for divs that do not have a z-index already defined
            if( !divs[i].getStyle('z-index') ) {
                divs[i].setStyle('z-index',z--);
            }
        }
    },
        
    parseRelevantData: function( obj, match ) {
        var relevant = {};
        for( var key in obj ) {
            // add to relevant data only if our match selector is present
            if( key.match( match ) ) {
                var truncatedKey = key.replace( match, '' );
                relevant[truncatedKey] = obj[key];
            }
        }
        
        return relevant;
    },
    
    submit_one : function( path, pre, num, onSuccess ) {
        
        // element ID
        var elementID = pre + num; 

        var domElement = $(elementID);

        // check to make sure there is a domElement
        // for that id structure
        if( domElement ) {
        
            var match = pre + '_' + num + '_';
            var elementList = [];
                
            // get JSON representation
            var elementData = domElement.toJSON();
            
            // parse only relevant data per our prefix
            elementData = this.parseRelevantData( elementData, match );
            
            // Rest API expects an array even when a single JSON object
            elementList.push(elementData);
            
            // create xhr
            // FIXME: This is a placeholder, we need to handle
            //        these responses appropriately
            var jsonRequest = new Request({
                url: path, 
                onSuccess: function(responseText, responseXML) {
                    // do something with success string, etc.
                    var response = JSON.decode(responseText);
                    // waUtil.log('CODE: ' + response.code + '\nTEXT: ' + response.text);
                    if( onSuccess ) {
                        onSuccess( response );
                    }
                },
                onFailure: function(xhr) {
                    // do something with failure string, etc.
                    //var response = JSON.decode(xhr.responseText);
                    waUtil.log(xhr);
                    // waUtil.log('CODE: ' + response.code + '\nTEXT: ' + response.text);
                },
                onTimeout: function(xhr) {
                    // do something with timeout
                    var response = JSON.decode(xhr.responseText);
                    waUtil.log(xhr);
                    // waUtil.log('CODE: ' + response.code + '\nTEXT: ' + response.text);
                }
            }).send( JSON.encode(elementList) );
        }
    },
    
    submit_all : function( path, pre, onSuccess ) {

        // grab a collection of our containers
        var elements = $$('.wa_' + pre);
        
        // check for element collection
        if( elements ) {
            var elementList = [];
            
            elements.each(function( element ) {
                var num = element.get('id').replace( pre, '' );
                
                // get JSON representation
                var elementData = element.toJSON();
                
                var match = pre + '_' + num + '_';
                
                // we only want data with the prefix we have chosen
                elementData = this.parseRelevantData( elementData, match );
                
                elementList.push( elementData );
            }.bind(this));
            
            var jsonRequest = new Request.JSON({
                url: path, 
                onSuccess: function(responseJSON, responseString) {
                    // do something with success string, etc.
                    if( onSuccess ) {
                        onSuccess( responseJSON, responseString );
                    }
                },
                onFailure: function(xhr) {
                    // do something with failure string, etc.
                    this.log('failed: ' + xhr.status + ' text: ' + xhr.responseText);
                },
                onTimeout: function() {
                    // do something with timeout string, etc.
                    this.log('timeout');
                }
            }).send( JSON.encode(elementList) );
        }
    },
    
    logout : function() {
        return this.submitAction('logout');
    },
    
    submitAction : function(action, formData) {
        // if host is in the dom, we are using a new WA page and need to generate a form
        if( $('host') ) {
            var host     = $('host').get('value');
            var username = $('username').get('value');
            
            if( !formData ) formData = {};
            
            var form     = new Element('form', {
                'action'  : '/v4cgi' + username + '/' + $('usertype').get('value') + '.pl',
                'enctype' : 'x-www-form-urlencoded',
                'id'      : 'wa',
                'method'  : 'post',
                'target'  : ( formData.target ) ? formData.target : ''
            });
            
            // FIXME:  we need to determine which links actually need this parameter
            // and include it in formData rather than checking for it in the dom here
            if( $('deployment') && !formData.hasOwnProperty('deployment') ) {
                new Element( 'input', {
                    'type'  : 'hidden',
                    'name'  : 'deployment',
                    'value' : $('deployment').get('value')
                } ).inject( form );
            }
            
            // add our required fields of action and UserPass
            formData.action   = action;
            formData.UserPass = $('sid').get('value');
            // add hidden inputs to the form for each property in our formData
            for( var fieldName in formData ) {
                if (formData.hasOwnProperty(fieldName)) {
                    var element = new Element( 'input', {
                        'type'  : 'hidden',
                        'name'  : fieldName,
                        'value' : formData[fieldName]
                    } ).inject( form );
                }
            }
            
            form.inject($(document.body));
            try { form.submit(this); }
            catch(e){} // silence IE errors
        } else { // we are in the old application so can just set the form fields and submit
            var waForm = $('wa');
            $('action').set('value', action);
            for( var fieldName in formData ) {
                if( $(fieldName) ) {
                    $(fieldName).set('value', formData[fieldName]); 
                } else {
                    new Element('input', {
                        'type'  : 'hidden',
                        'id'    : fieldName,
                        'name'  : fieldName,
                        'value' : formData[fieldName]
                    }).inject( waForm );
                }
            }
            waForm.submit( this );
        }
        return false;
    },
    
    post : function( url, data ) {
        if( !url ) url = document.URL;
        var json = JSON.encode( data );
        var form = new Element('form', {
            action  : url,
            enctype : 'text/plain',
            id      : 'wa',
            method  : 'post'
        });
        new Element('input', {
            type  : 'hidden',
            name  : 'data',
            value : json
        }).inject(form);
        form.inject($(document.body));
        try { form.submit(this); }
        catch(e){} // silence IE errors
        return false;
    },
    
    openWindow : function(comp,name,attr) {
        // if a name is being passed in
        if ( typeof name !== "undefined" && name !== null ) {
            // replace spaces with _ and all other illeal characters with the emptystring
            name = String(name).replace(/\s/g, '_').replace(/[^a-z0-9_]/gi, '');
        }
        
        var newWindow = window.open(comp,name,attr);
        newWindow.focus();
    },

    openEbook : function(server_name,wa_alias,ebookurl,ebookid,secflag) {
        var win_url = ebookurl;
        var win_options = '';

        if ( secflag === "on" ) {
            var upass = $('UserPass').value;
            win_url = 'http://' + server_name + '/' + wa_alias + '/extra/ebookwrapper/index.tpl?';
            win_url += 'ebook_url=' + ebookurl;
            win_url += '&UserPass=' + upass;
            win_options =
'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbar=no,resizable,copyhistory=yes,width=960,height=720,left=25,top=25,screenX=25,screenY=25';
        }
        
        this.openWindow( win_url, ebookid, win_options );
        
        return false;
    },

    log : function( data ) {
        if( window.console && console.log ) {
            console.log( data );
        }
    },
    
    onBeforeUnload : function() {
        var rtn = false;
        var l = this._unload_events.length;
        for( var i = 0; i < l; i++ ) {
            var msg = this._unload_events[i]();
            if( msg ) rtn = msg;
        } 
        if( rtn ) return rtn;
        else return;
    },
    
    addUnloadEvent : function(method) {
        if( !this.hasOwnProperty('_unload_events') ) {
            this._unload_events = [];
            window.onbeforeunload = this.onBeforeUnload.bind(this);
        }
        //ensure that the method is not registered twice
        this.removeUnloadEvent( method );
        this._unload_events.push( method );
    },
    
    removeUnloadEvent : function(method) {
        if( this.hasOwnProperty('_unload_events') ) {
            for( var i = this._unload_events.length; --i >= 0; ) {
                if( this._unload_events[i] === method ) {
                    this._unload_events.splice(i, 1 );
                    break;
                }
            }
        }
    },
    
    dump : function( object, tabs ) {
        if( object == null ) {
            object = this;
        }
        if( tabs == null ) {
            tabs = '';
        }
        for( var key in object ) {
            if( typeOf(object[key]) == 'array' || typeOf(object[key]) == 'object' ) {
                this.log(tabs + key + ' : ');
                this.dump( object[key], tabs + '    ' );
            } else if( typeof(object[key]) != 'function') {
                this.log(tabs + key + ' : ' + object[key]);
            }
        }
    }
});

// instantiate class
var waUtil = new WA.Util();

// For ease of compatibility with legacy pages we create a global openWindow method.
// All *new* javascript should use the scoped waUtil.openWindow method.
var openWindow = waUtil.openWindow;

//ditto for openEbook
var openEbook = waUtil.openEbook;

