/***Javascript functions to use with ajax.
ajaxCall(strURL, xmlData, receiveFunction, blnAsync) - calls to specified url with data
ajaxSimpleSendRequest((strURL, strReceiveFunction, strAction, strReturnFunction) - wraps call to ajaxcall
ajaxArg(strName, strValue) - creates an argument to send to the ajaxSimpleSendRequest
createXMLDOM - called in ajaxSimpleSendRequest to create an xml document depending on the browser
AddNodeToXml - Helper function used in ajaxSimpleSendRequest to create xml arguments
***/



/*****************************************************************************************/

var mblnDefaultAsync = true;
var mblnAjaxConnectionClose = false; /* for proxies that don't behave well this needs to be set to true, for integrated authentication this needs to be false. */

//This is the main javascript function called directly by some ajax calls in the application
//ajaxSimpleSendRequest (below) wraps the call to this function and includes the functionality to build the xmldom
function ajaxCall(strURL, xmlData, receiveFunction, blnAsync) {

    var ajaxRequest = null;

    if (typeof xmlData == 'undefined') {
        xmlData = null;
    }
    else if (typeof (xmlData) == 'object') {
        xmlData = getXmlString(xmlData);
    }
    if (typeof blnAsync == 'undefined') {
        blnAsync = mblnDefaultAsync;
    }
    if (window.XMLHttpRequest) {
        // branch for native XMLHttpRequest object
        ajaxRequest = new XMLHttpRequest();
    }
    else if (window.ActiveXObject) {
        // branch for IE6-/Windows ActiveX version
        ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
    }

    if (ajaxRequest) {
        ajaxRequest.open("POST", strURL, blnAsync);

        //        ajaxRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        ajaxRequest.setRequestHeader("Content-length", xmlData.length);

        if ((mblnAjaxConnectionClose == true) && (getInternetExplorerVersion() != 6)) {
            ajaxRequest.setRequestHeader("Connection", "close");
        }


        //this seems to be the opposite of what i expected
        //firefox3 onreadystatechange doesnt fire for synchronous
        //so blnAsync should be false, but it only works like this        
        if (blnAsync) {

            ajaxRequest.onreadystatechange = function() {
                DocumentReady(ajaxRequest, receiveFunction);
            }
        }

        //debugger;

        //'<?xml version="1.0" encoding="ISO-8859-1" ?>'
        ajaxRequest.send(xmlData);

        if (!blnAsync) {
            // manually fire the event if synchronous
            DocumentReady(ajaxRequest, receiveFunction);
        }
    }

};

/*****************************************************************************************/

function DocumentReady(ajaxRequest, receiveFunction) {
    // only if req shows "complete"
    if ((ajaxRequest.readyState == 4) || (ajaxRequest.readyState == 'complete')) {
        // only if "OK"
        if (ajaxRequest.status == 200) {
            if (ajaxRequest.responseXML.documentElement != null) {
                var objResponse = ajaxRequest.responseXML.documentElement;
                if ((typeof (receiveFunction) != 'undefined') && (receiveFunction != '')) {
                    eval(receiveFunction + '(objResponse)');
                }
            }
        }
        else {
            if (ajaxRequest.status == 0) {
                //Process Aborted, normally the user has navigated to a different page.
                return;
            }
            var lStatusText = ajaxRequest.status + ': ';
            switch (ajaxRequest.status) {
                case 401:
                    lStatusText += 'Unauthorized';
                    break;
                case 403:
                    lStatusText += 'Forbidden ';
                    break;
                case 404:
                    lStatusText += 'Not Found ';
                    break;

                case 405:
                    lStatusText += 'Method Not Allowed';
                    break;
                case 406:
                    lStatusText += 'Not Acceptable';
                    break;
                case 407:
                    lStatusText += 'Proxy Authentication Required';
                    break;
                case 408:
                    lStatusText += 'Request Timeout';
                    break;
                case 412:
                    lStatusText += 'Precondition Failed';
                    break;

                case 500:
                    lStatusText += 'Internal Server Error';
                    break;
                case 501:
                    lStatusText += 'Not Implemented';
                    break;
                case 503:
                    lStatusText += 'Service Unavailable';
                    break;
                case 504:
                    lStatusText += 'Gateway Timeout';
                    break;
                case 505:
                    lStatusText += 'HTTP Version Not Supported';
                    break;                 
            }
            var strErrorMessage = 'Ajax request failed, code (' + lStatusText + ')';
            raiseMessage('stoperror', strErrorMessage, '');
            if ((typeof (receiveFunction) != 'undefined') && (receiveFunction != '')) {
                eval(receiveFunction + '(null)');
            }
        }
    }
};


/*****************************************************************************************/

/*


Example: 
//ajaxSimpleSendRequest('~/page/system/ajax/mypage.aspx', 'myFunction', 'action', '', new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value'));
	
Args:
strURL					Required, the page that will handle the request.
strReceiveFunction		Required, the function that you wish to receive the response. 
strAction				Optional, the action parameter used in the Process method in the handling ajax page. 
strReturnFunction		Optional, the function that the receive function will use for processing different actions. 
argArray				Optional Array, additional argument list must be in the form of ajaxArg e.g. 
new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value')

*/

function ajaxSimpleSendRequest(strURL, strReceiveFunction, strAction, strReturnFunction) {
    //uses function below to create xml document depending on browser
    var blnAsync = mblnDefaultAsync;
    var xmlDoc = createXMLDOM(blnAsync);
    var xmlTable = xmlDoc.createElement('table');
    var xmlRow = xmlDoc.createElement('row');

    xmlDoc.appendChild(xmlTable);
    xmlTable.appendChild(xmlRow);

    strReturnFunction = (typeof (strReturnFunction) == 'undefined') ? '' : strReturnFunction;
    strAction = (typeof (strAction) == 'undefined') ? '' : strAction;

    //Add the main arguments to the xml
    AddNodeToXml(xmlDoc, xmlRow, 'action', strAction);
    AddNodeToXml(xmlDoc, xmlRow, 'return_function', strReturnFunction);

    //Add the arguments to the xml
    var intArgLength = arguments.length;
    for (var intIndex = 4; intIndex < intArgLength; intIndex++) {
        var objArg = arguments[intIndex];
        if (objArg.getType() == 'ajaxArg') {
            AddNodeToXml(xmlDoc, xmlRow, objArg.Name, objArg.Value);
        }
    }
    //call main ajax function
    ajaxCall(strURL, xmlDoc, strReceiveFunction, blnAsync);

};

/*

Used as above but for multiple rows.
  
Example: 
//ajaxComplexSendRequest('~/page/system/ajax/mypage.aspx', 'myFunction', 'action', ''
, [new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value')), new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value'))]
, [new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value')), new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value'))]
, [new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value')), new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value'))]
);
  
*/

function ajaxComplexSendRequest(strURL, strReceiveFunction, strAction, strReturnFunction) {
    //uses function below to create xml document depending on browser
    var blnAsync = mblnDefaultAsync;
    var xmlDoc = createXMLDOM(blnAsync);
    var xmlTable = xmlDoc.createElement('table');
    var objArgList = null;
    var objArg = null;
    var intArgCount = 0;

    var xmlRow;
    xmlDoc.appendChild(xmlTable);
    strReturnFunction = (typeof (strReturnFunction) == 'undefined') ? '' : strReturnFunction;
    strAction = (typeof (strAction) == 'undefined') ? '' : strAction;

    //Add the arguments to the xml
    var intArgLength = arguments.length;
    for (var intIndex = 4; intIndex < intArgLength; intIndex++) {
        objArgList = arguments[intIndex];

        xmlRow = xmlDoc.createElement('row');
        xmlTable.appendChild(xmlRow);

        //Add the main arguments to the xml
        AddNodeToXml(xmlDoc, xmlRow, 'action', strAction);
        AddNodeToXml(xmlDoc, xmlRow, 'return_function', strReturnFunction);

        intArgCount = objArgList.length;
        for (var intArgIndex = 0; intArgIndex < intArgCount; intArgIndex++) {
            objArg = objArgList[intArgIndex];
            if (objArg.getType() == 'ajaxArg') {
                AddNodeToXml(xmlDoc, xmlRow, objArg.Name, objArg.Value);
            }
        }
    }
    //call main ajax function
    ajaxCall(strURL, xmlDoc, strReceiveFunction, blnAsync);

};

/*

Used as above but for multiple rows, multi action.
  
Example: 
ajaxMultiSendRequest('~/page/system/ajax/mypage.aspx', 'myFunction', '', [
action:'actionname',args:[new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value')), new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value'))]
, action:'actionname',args:[new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value')), new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value'))]
, action:'actionname',args:[new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value')), new Array(new ajaxArg('arg1','arg1value'), new ajaxArg('arg2','arg2value'))]
]);
            
or
var actions = new Array();
    
actions.push({ action: 'deleteFile', args: [
new ajaxArg('asset_id', GetXmlNodeText(this.mCurrentSelection[i][8]))
, new ajaxArg('url', this.CurrentPath)
, new ajaxArg('name', GetXmlNodeText(this.mCurrentSelection[i][0]))
, new ajaxArg('is_secure_asset', GetXmlNodeText(this.mCurrentSelection[i][2]))
] });
ajaxMultiSendRequest('~/page/system/ajax/mypage.aspx', 'myFunction', '', actions);                                                      
                                                        
  
*/

function ajaxMultiSendRequest(strURL, strReceiveFunction, strReturnFunction, rows) {
    //uses function below to create xml document depending on browser
    var blnAsync = mblnDefaultAsync;
    var xmlDoc = createXMLDOM(blnAsync);
    var xmlTable = xmlDoc.createElement('table');
    var objArgList = null;
    var objArg = null;
    var intArgLength = 0;
    var intArgCount = 0;


    var xmlRow;
    xmlDoc.appendChild(xmlTable);
    strReturnFunction = (typeof (strReturnFunction) == 'undefined') ? '' : strReturnFunction;
    //strAction = (typeof (strAction) == 'undefined') ? '' : strAction;

    //Add the arguments to the xml
    intArgLength = rows.length;
    for (var intIndex = 0; intIndex < intArgLength; intIndex++) {
        objArgList = rows[intIndex];

        if (typeof (objArgList.action) != 'string') {
            throw "action not defined";
        }
        if (typeof (objArgList.args) != 'object') {
            throw "args not defined";
        }


        xmlRow = xmlDoc.createElement('row');
        xmlTable.appendChild(xmlRow);

        //Add the main arguments to the xml
        AddNodeToXml(xmlDoc, xmlRow, 'action', objArgList.action);
        AddNodeToXml(xmlDoc, xmlRow, 'return_function', strReturnFunction);

        intArgCount = objArgList.args.length;
        for (var intArgIndex = 0; intArgIndex < intArgCount; intArgIndex++) {
            objArg = objArgList.args[intArgIndex];
            if (objArg.getType() == 'ajaxArg') {
                AddNodeToXml(xmlDoc, xmlRow, objArg.Name, objArg.Value);
            }
        }
    }
    //call main ajax function
    ajaxCall(strURL, xmlDoc, strReceiveFunction, blnAsync);

};


/*****************************************************************************************/

//Creates an ajaxarg object to send to the ajaxSimpleSendRequest function above
function ajaxArg(strName, strValue) {
    this.Name = strName;
    this.Value = strValue;
};

ajaxArg.prototype = {
    Name: '',
    Value: '',

    getType: function() {
        return 'ajaxArg';
    }
}


/*****************************************************************************************/


// This function is now defunct.
function ajaxStateHandler() {
    // only if req shows "complete"
    if (ajaxRequest.readyState == 4) {
        // only if "OK"
        if (ajaxRequest.status == 200) {
            //debugger;
            if (ajaxRequest.responseXML.documentElement != null) {
                var objResponse = ajaxRequest.responseXML.documentElement;
                var strMethod = objResponse.getElementsByTagName('method')[0].firstChild.data;
                var objStatus = objResponse.getElementsByTagName('status')[0];
                var objResults = objResponse.getElementsByTagName('result');
                var intResultCount = objResults.length;
                var intStatus = 0;
                var strErrorMessage = '';

                if (objStatus != null) {
                    intStatus = GetXmlNodeText(objStatus.getElementsByTagName('status')[0]);
                    strErrorMessage = GetXmlNodeText(objStatus.getElementsByTagName('error_message')[0]);
                }

                if (intStatus == 0) {

                    for (var intResultIndex = 0; intResultIndex < intResultCount; intResultIndex++) {
                        var objResult = objResults[intResultIndex];
                        eval(strMethod + '(objResult)');
                    }
                }
                else {
                    raiseMessage('stoperror', strErrorMessage, '');
                }
            }
        }
    }
};

/*****************************************************************************************/

//creates an xml document depending on the browser
function createXMLDOM(blnAsync) {
    var xmlDoc;

    blnAsync = (typeof (blnAsync) == 'undefined') ? false : blnAsync == mblnDefaultAsync;

    // code for IE
    if (window.ActiveXObject) {
        xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = blnAsync;
        xmlDoc.loadXML('<?xml version="1.0" encoding="ISO-8859-1" ?>');
    } // code for Mozilla, Firefox, Opera, etc.
    else if ((document.implementation) && (document.implementation.createDocument)) {
        xmlDoc = document.implementation.createDocument("", "", null);
        xmlDoc.async = blnAsync;
        try {
            //TODO: this fails for safari, need to load xml another way.
            xmlDoc.load('<?xml version="1.0" encoding="ISO-8859-1" ?>');
        } catch (ex) { }
    }
    else {
        alert('Your browser cannot handle this script');
    }
    return (xmlDoc);
};

/*****************************************************************************************/

//Helper function used in ajaxSimpleSendRequest to create xml arguments
function AddNodeToXml(xmlDoc, xmlRow, strName, value) {

    var xmlNewNode = xmlDoc.createElement(strName);
    xmlNewNode.appendChild(xmlDoc.createTextNode(value));
    xmlRow.appendChild(xmlNewNode);

};

function ajax_callback(filename, clientId, nodeLinkGuid, postbackArgs, onCompleted, disableForm, enableForm, qs) {
    var actions = new Array();
    var viewstateControl = document.getElementById('ctl00___VIEWSTATE_CONTROL_GUID');
    var viewstateControlGuid = '';

    qs = (typeof (qs) == 'undefined') ? '' : '&' + qs;

    if (disableForm == true) {
        formDisable(true);
    }

    if (viewstateControl != null)
        viewstateControlGuid = viewstateControl.value;

    actions.push({ action: 'ajax_callback', args: [
                                        new ajaxArg('clientId', clientId)
                                        , new ajaxArg('nodeLinkGuid', nodeLinkGuid)
                                        , new ajaxArg('postbackArgs', postbackArgs)
                                        , new ajaxArg('ContentGuid', MiWeb.mArgs.ContentGuid)
                                        , new ajaxArg('PageGuid', MiWeb.mArgs.PageGuid)
                                        , new ajaxArg('LocaleGuid', MiWeb.mArgs.LocaleGuid)
                                        , new ajaxArg('SiteGuid', MiWeb.mArgs.SiteGuid)
                                        , new ajaxArg('SiteUrlGuid', MiWeb.mArgs.SiteUrlGuid)
                                        , new ajaxArg('onCompleted', onCompleted)
                                        , new ajaxArg('Filename', filename)
                                        , new ajaxArg('enableForm', enableForm)
                                        , new ajaxArg('viewstateControlGuid', viewstateControlGuid)
                                       ]
    });
    ajaxMultiSendRequest(MiWeb.resolveUrl('~/page/system/ajax/control_callback.aspx') + '?utc=' + new Date().getTime().toString() + qs, 'ajax_callback_rec', onCompleted, actions);
};

function ajax_callback_rec(objResults) {
    //    if (MiWebAjax.checkAjaxStatus(objResults) == false) {
    //        debugger;
    //        return;
    //    }
    if (objResults == null) return false;
    var rows = objResults.getElementsByTagName('row');
    var intRowCount = rows.length;
    var cell;
    var status;
    var message;
    var func;
    var control;
    var enableForm;
    var js;
    var aE = document.activeElement;
    var aId = '';

    if (aE != null && typeof (aE.id) != 'undefined')
        aId = aE.id;
    aE = null;

    for (intRowIndex = 0; intRowIndex < intRowCount; intRowIndex++) {
        cell = rows[intRowIndex].getElementsByTagName('cell');
        status = GetXmlNodeText(cell[0]);
        message = GetXmlNodeText(cell[1]);
        enableForm = GetXmlNodeText(cell[4]);

        if (enableForm == 'true') {
            formDisable(false);
        }

        if (status == 0) {
            control = $(GetXmlNodeText(cell[2]));
            func = GetXmlNodeText(cell[3]);
            if (control != null) {
                while (control.firstChild) {
                    control.removeChild(control.firstChild);
                }
                control.innerHTML = GetXmlNodeText(cell[5]);
            }
            if ((func != null) && (func != '')) {
                var row = rows[intRowIndex];
                eval(func + '(row);');
            }
            js = GetXmlNodeText(cell[6]);

            if ((js != null) && (js != '')) {
                try {
                    eval(js);
                } catch (exjs) { }
            }
        }
        else {
            raiseMessage('stoperror', message, '');
        }
    }

    try {
        if (typeof (aId) != '') {
            //setTimeout('try {$(aId).focus();} } catch (ex) {alert(ex.message);}', 100);
            setTimeout('try{var ctl = $(\'' + aId + '\'); if(ctl != null){ctl.focus();ctl.select();}}catch(ex){}', 100);
        }
    } catch (ex) { alert(ex.message); }

};

var MiWebAjax = {

    checkAjaxStatus: function(objResults) {
        if (objResults == null) return false;
        var intStatus = GetXmlNodeText(objResults.getElementsByTagName('status')[0]);
        var strMessage;
        if (intStatus != '0') {
            strMessage = GetXmlNodeText(objResults.getElementsByTagName('error_message')[0]);

            raiseMessage('stoperror', strMessage);

            if (strMessage == 'Unauthorised access exception') {
                document.location.href = MiWeb.resolveUrl('~/login.aspx') + '?ReturnUrl=' + document.location.href.URLEncode();
            }

            return false;
        }
        return true;
    },

    getText: function(objResults, tagName, index) {
        index = (typeof (index) == 'undefined') ? 0 : parseInt(index, 10);
        var tag = objResults.getElementsByTagName(tagName);
        if ((tag != null) && (tag.length > index)) {
            return GetXmlNodeText(tag[index]);
        }
        return null;
    },

    GetType: function() { return 'ajax'; }
};
    
    
