/*jslint browser: true, cap: false, glovar: true, passfail: false, undef: false, white: false */
/*global SONGHAY YAHOO */

(function(){

    SONGHAY.ui.Ajax =
    {
        client:null,
        request:null,
        requestRunning:false,
        serverCommand:'',
        targetId:'',

        call:function()
        {
            var vRequestMethod = (arguments.length > 0) ? arguments[0] : 'GET';
            var vUri = (arguments.length > 1) ? arguments[1] : undefined;
            if(vUri === undefined)
            {
                alert('The URI of the AJaX call is undefined.');
                return;
            }

            self.targetId = (arguments.length > 2) ? arguments[2] : '';

            if(!self.checkEnvironment()) { return; }
            if(!self.canRun()) { return; }

            self.requestRunning = true;

            var vAjaxPassthroughArgument = (arguments.length > 3) ? arguments[3] : 'display';
            var vAjaxPostData = (arguments.length > 4) ? arguments[4] : null;
            var vContentType = (arguments.length > 5) ? arguments[5] : 'application/x-www-form-urlencoded';

            if(vRequestMethod.toUpperCase() == 'POST')
            {
                YAHOO.util.Connect.setDefaultPostHeader(false);
                YAHOO.util.Connect.initHeader("Content-Type", vContentType);
            }

            self.request =
                YAHOO.util.Connect.asyncRequest(
                    vRequestMethod,
                    vUri,
                    { 
                      success:self.callHandlerY, 
                      failure:self.callHandlerN,
                      argument:vAjaxPassthroughArgument
                    },
                    vAjaxPostData);

            var vMarkup = '<div class="AjaxMessage">Sending request&#8230;<\/div>';
            self.writeToTarget(self.targetId, vMarkup, true);
        },

        callHandlerN:function(o)
        {
            var vMarkup = '<div class="AjaxMessage">'+ o.statusText + '<\/div>';
            self.writeToTarget(self.targetId, vMarkup, false);
            self.request = null;
            self.requestRunning = false;
        },

        callHandlerY:function(o)
        {
            var vMarkup;

            if(o && (o.status !== undefined ) && (o.status !== 0) && (o.responseText !== undefined))
            {
                self.requestRunning = false;

                if(o.responseText.length === 0)
                {
                    vMarkup = '<div class="AjaxMessage">The server returned no data.<\/div>';
                    self.writeToTarget(self.targetId, vMarkup, false);
                }
                else
                {
                    self.writeToTarget(self.targetId, o.responseText, false, o.argument);
                }
            }

            self.request = null;
        },

        canRun:function()
        {
            var ret = false;
            var o = null;

            if(self.requestRunning)
            {
                ret = window.confirm('A previous request is running.\nCancel request?');
            }
            else
            {
                o = YAHOO.util.Dom.get(self.targetId);
                if(o){ o.innerHTML = ''; }

                ret = true;
            }

            return ret;
        },

        checkEnvironment:function()
        {
            if(!self.client)
            {
                alert('The AJaX Client is null or undefined.');
                return false;
            }

            if(!self.client.getUri)
            {
                alert('The AJaX Client URI getter, getUri(), is null or undefined.');
                return false;
            }

            return true;
        },

        display:function(e)
        {
            if(!self.checkEnvironment()) { return; }

            if(e) { YAHOO.util.Event.preventDefault(e); }

            //Look for pass-through object from YAHOO.util.Event.addListener():
            var oEventPassThrough = (arguments.length > 1) ? arguments[1] : null;
            if(oEventPassThrough && oEventPassThrough.serverCommand){} else { return; }

            if(oEventPassThrough.targetId === undefined){ oEventPassThrough.targetId = 'DisplayBlock'; }
            var vTargetId = (arguments.length > 2) ? arguments[2] : oEventPassThrough.targetId;

            if(oEventPassThrough.ajaxPassthroughArgument === undefined){ oEventPassThrough.ajaxPassthroughArgument = 'display'; }
            var vAjaxPassthroughArgument = (arguments.length > 3) ? arguments[3] : oEventPassThrough.ajaxPassthroughArgument;

            if(oEventPassThrough.mediaType === undefined){ oEventPassThrough.mediaType = 'application/xml'; }
            var vMediaType = (arguments.length > 4) ? arguments[4] : oEventPassThrough.mediaType;

            if(oEventPassThrough.uriCase === undefined){ oEventPassThrough.uriCase = 'default'; }
            var vUriCase = (arguments.length > 5) ? arguments[5] : oEventPassThrough.uriCase;

            self.serverCommand = oEventPassThrough.serverCommand;
            var vUri = self.client.getUri(vUriCase, self.serverCommand);

            self.call(
                'GET',
                vUri,
                vTargetId,
                vAjaxPassthroughArgument,
                null,
                vMediaType);
        },

        getAndDisplay:function(e)
        {
            if(!self.checkEnvironment()) { return; }

            //CONVENTION: Look for pass-through object from YAHOO.util.Event.addListener():
            var oEventPassThrough = (arguments.length > 1) ? arguments[1] : null;
            if(oEventPassThrough && oEventPassThrough.serverCommand){} else { return; }

            if(oEventPassThrough.targetId === undefined){ oEventPassThrough.targetId = 'DisplayBlock'; }
            var vTargetId = (arguments.length > 2) ? arguments[2] : oEventPassThrough.targetId;

            if(oEventPassThrough.id === undefined){ oEventPassThrough.id = null; }
            var vId = (arguments.length > 3) ? arguments[3] : oEventPassThrough.id;

            if(oEventPassThrough.ajaxPassthroughArgument === undefined){ oEventPassThrough.ajaxPassthroughArgument = 'display'; }
            var vAjaxPassthroughArgument = (arguments.length > 4) ? arguments[4] : oEventPassThrough.ajaxPassthroughArgument;

            if(oEventPassThrough.mediaType === undefined){ oEventPassThrough.mediaType = 'application/xml'; }
            var vMediaType = (arguments.length > 5) ? arguments[5] : oEventPassThrough.mediaType;

            if(oEventPassThrough.uriCase === undefined){ oEventPassThrough.uriCase = 'default'; }
            var vUriCase = (arguments.length > 6) ? arguments[6] : oEventPassThrough.uriCase;

            if(e && !vId)
            {
                YAHOO.util.Event.preventDefault(e);
                var o = YAHOO.util.Event.getTarget(e);
                if(o){}else { return; }

                vId = o.id;

                //CONVENTION: look for target IDs with pattern item_#_#:
                if(vId.indexOf('item_') != -1) { vId = vId.replace(/item_.+_/,''); }
            }

            self.serverCommand = oEventPassThrough.serverCommand;
            var vUri = self.client.getUri(vUriCase, self.serverCommand, vId);

            self.call(
                'GET',
                vUri,
                vTargetId,
                vAjaxPassthroughArgument,
                null,
                vMediaType);
        },

        postAndDisplay:function(e)
        {
            if(!self.checkEnvironment()) { return; }

            if(e) { YAHOO.util.Event.preventDefault(e); }

            var o = (e) ? YAHOO.util.Event.getTarget(e) : null;

            //Look for pass-through object from YAHOO.util.Event.addListener():
            var oEventPassThrough = (arguments.length > 1) ? arguments[1] : null;

            if(oEventPassThrough.targetId === undefined){ oEventPassThrough.targetId = 'DisplayBlock'; }
            var vTargetId = (arguments.length > 2) ? arguments[2] : oEventPassThrough.targetId;

            if(oEventPassThrough.ajaxPassthroughArgument === undefined){ oEventPassThrough.ajaxPassthroughArgument = 'display'; }
            var vAjaxPassthroughArgument = (arguments.length > 3) ? arguments[3] : oEventPassThrough.ajaxPassthroughArgument;

            if(oEventPassThrough.mediaType === undefined){ oEventPassThrough.mediaType = 'application/xml'; }
            var vMediaType = (arguments.length > 4) ? arguments[4] : oEventPassThrough.mediaType;

            if(oEventPassThrough.uriCase === undefined){ oEventPassThrough.uriCase = 'default'; }
            var vUriCase = (arguments.length > 5) ? arguments[5] : oEventPassThrough.uriCase;

            var oUI = self.client.ui;

            if(o && o.id)
            {
                //A target with an id was found for any XML getter.
            }
            else if(oEventPassThrough && oEventPassThrough.target)
            {
                //A target was added (in self.client.dataForm.confirm()) because MSIE <=7.0 sucks:
                o = oEventPassThrough.target;
            }
            else if(oEventPassThrough.form)
            {
                //Construct a "fake" object that looks like a form element:
                o = {};
                o.form = oEventPassThrough.form;
            }

            var data = '';
            var vUri = '';

            if(oEventPassThrough && oEventPassThrough.serverCommand)
            {
                if(oEventPassThrough.stringGetter)
                {
                    data = (o) ? oEventPassThrough.stringGetter(o) : oEventPassThrough.stringGetter();
                    if(data == 'false') { return; }
                }
                else if(oEventPassThrough.xmlGetter)
                {
                    data = (o) ? oEventPassThrough.xmlGetter(o) : oEventPassThrough.xmlGetter();
                    if(data == 'false') { return; }
                }
                else if(o.form)
                {
                    data = oUI.DataValidation.buildXmlString(o.form);
                }

                self.serverCommand = oEventPassThrough.serverCommand;
                vUri = self.client.getUri(vUriCase,self.serverCommand);

                if((vUri.length > 0) && (data.length > 0))
                {
                    self.call(
                        'POST',
                        vUri,
                        vTargetId,
                        vAjaxPassthroughArgument,
                        data,
                        vMediaType);
                }
            }
        },

        writeToTarget:function(vTargetId, vTargetContent, vIsCall)
        {
            if(!self.checkEnvironment()) { return; }

            var oTarget = YAHOO.util.Dom.get(vTargetId);

            var oAjaxPassthroughArgument = (arguments.length > 3) ? arguments[3] : null;

            var o = self.client.AjaxTargets[vTargetId];
            if(o)
            {
                if(vIsCall && o && o.callFunction)
                {
                    o.callFunction(oTarget, oAjaxPassthroughArgument);
                }
                else if(o && o.responseFunction)
                {
                    o.responseFunction(oTarget, vTargetContent, oAjaxPassthroughArgument);
                }
            }
            //Use default ajax targets:
            else if(vIsCall)
            {
                o = self.client.AjaxTargets._default;
                if(o && o.callFunction)
                {
                    o.callFunction(oTarget, oAjaxPassthroughArgument);
                }
            }
            else if(!vIsCall)
            {
                o = self.client.AjaxTargets._default;
                if(o && o.responseFunction)
                {
                    o.responseFunction(oTarget, vTargetContent, oAjaxPassthroughArgument);
                }
            }
        }
    };

    //Module-level "this":
    var self = SONGHAY.ui.Ajax;

})();
