﻿// JScript File
function ASyncHandler()
{
    //////////////////////////////////////////////////////////////
    //private member
    var _presevedStateNumber = 1;
    var _stateHolders = new Array();
    var _RaiseErrorDelagte = null;
    var _OnCloseDelagte = null;
    var _operationCode = null;
    //////////////////////////////////////////////////////////////
    //public member
    this.BeginInvoke = function (stateID,stateXML,location,additonalParams,pageParameters)
    {
        try
        {
            _operationCode = pageParameters;
            var oStateHolder = AddStateHolder(stateID,stateXML,location,"preparation",additonalParams,pageParameters);
            var sExpression = String.prototype.Format("_RunSoapCommand2({0},{1},'m_ASyncObject.EndInvoke'","arguments[5]","arguments[6]");
            var oSB = new StringBuilder();
            for(var index=7;index<arguments.length;index++)
            {
                oSB.Append(String.prototype.Format(",arguments[{0}]",index));
            }
            sExpression +=oSB.ToString()+");";
            
            eval(sExpression);
        }
        catch(err)
        {
            return err.description;
        }
        return "";
    }
    
    this.EndInvoke = function (SOAPResult)
    {   
        var sStateID = SOAPResult.StateID;
        //SOAPResult.error = true;
        //in case of error
        if(SOAPResult.error == true )
        {
            var oStateHolder = _stateHolders[sStateID];
            oStateHolder.Status = "error";
            oStateHolder.SOAPResult = SOAPResult;
            RaiseError(GetStateHolders("error"));
            return;
        }        
        //alert("ok");
        //in case of success close the state and clean the memory
        _CloseState(sStateID);
    }
    this.CloseStateHandler = function(SOAPResult)
    {
        var sStateID = SOAPResult.StateID;
        var oStateHolder = _stateHolders[sStateID];
        var isRollback = (oStateHolder.Status == "rollback");
        oStateHolder.Status = "closed";
        if(!isRollback)RaiseOnClose(oStateHolder);
        _operationCode = null;
    }
    
    this.IsLock = function (key)
    {
        return (key != null && _operationCode == key );
    }
    
    this.Available = function (location)
    {
        for(var key in _stateHolders) return false;
        /*if(_stateHolders.length == _presevedStateNumber) return false;
        else if( GetStateHolder(location)!= null ) return false;
        else if(_stateHolders.length == 0 && _presevedStateNumber) return true;*/
        return true;
    }
    
    
    this.NavigateToModule = function (stateID)
    {        
        var oStateHolder = _stateHolders[stateID];
        if( oStateHolder == null ) return false;
        var sLocation = oStateHolder.Location;
        ApplyPageParameters(oStateHolder.Parameters[4]);
        _SetGlobalVar("_PageParameters",String.prototype.Format("{0}&WebVar_AsyncLoad={1}",oStateHolder.PageParameters,"true"));
        window.top.main_frame.AO_Redirect(sLocation);
        
    }
    
    this.OnRaiseError = function (functionHandler)
    {
        if(typeof(functionHandler) == "string" )
        {
            _RaiseErrorDelagte = function(stateHolders)
            {
                eval(String.prototype.Format("{0}({1})",functionHandler,"stateHolders"));
            }
        }
        else if(typeof(functionHandler) == "function" )
        {
            _RaiseErrorDelagte = functionHandler;
        }
        var oStateHolderArr = GetStateHolders("error");
        if(oStateHolderArr!=null && oStateHolderArr.length > 0 )
        {
            RaiseError(oStateHolderArr);
        }
        _operationCode = null;
    }
    
    this.OnCloseState = function (functionHandler)
    {
        if(typeof(functionHandler) == "string" )
        {
            _OnCloseDelagte = function(stateHolder)
            {
                eval(String.prototype.Format("{0}({1})",functionHandler,"stateID"));
            }
        }
        else if(typeof(functionHandler) == "function" )
        {
            _OnCloseDelagte = functionHandler;
        }
        var oStateHolderArr = GetStateHolders("closed");
        if(oStateHolderArr!=null && oStateHolderArr.length > 0 )
        {
            RaiseOnClose(oStateHolderArr[0]);
        }
    }
    
    this.CloseState = function (stateID,rollBack)
    {
        rollBack = typeof(rollBack)=="undefined"?false:rollBack;
        try
        {
            if(rollBack) _stateHolders[stateID].Status = "rollback";
            _CloseState(stateID);
        }
        catch(err)
        {/**/}
    }
    
    this.CloseAllState = function ()
    {
        for(var sStateId in _stateHolders)
        {
            this.CloseState(_stateHolders[sStateId].StateID);
        }
    }
    
    this.PreserveStateXML = function (location)
    {
        var oStateHolder = GetStateHolder(location);
        if( oStateHolder == null ) return null;
        //RemoveStateHolder(oStateHolder.StateID);
        return oStateHolder.StateXML;
    }
    
    this.RemoveStateByLocation = function (location)
    {
        var oStateHolder = GetStateHolder(location);
        if( oStateHolder == null ) return null;
        RemoveStateHolder(oStateHolder.StateID);
    }
    
    this.RemoveStateById = function (stateId)
    {
        RemoveStateHolder(stateId);
    }

    this.CleanClosedState  = function ()
    {     
        for(var sStateId in _stateHolders)
        {
            if(_stateHolders[sStateId].Status == "closed" )
            {
                RemoveStateHolder(sStateId);
            }
        }
        
    }
    /////////////////////////////////////////////////////////////////
    //private methods
    function AddStateHolder(stateID,stateXML,location,status,additonalParams,pageParameters)
    {
        var oStateHolder = new StateHolder(location,additonalParams,pageParameters,null,stateXML,status,stateID);
        _stateHolders[stateID] = oStateHolder;
        return oStateHolder;
    }
    
    function RemoveStateHolder(discardStateID)
    {
        var oArr = new Array();
        for(var sStateId in _stateHolders)
        {
            var oStateHolder = _stateHolders[sStateId];
            if(oStateHolder.StateID != discardStateID )
            {
                oArr[sStateId] = oStateHolder;
            }
            else
            {
                oStateHolder.Finalize();
                oStateHolder = null;
            }
        }
        _stateHolders =  oArr;
        return true;
    }
    
    function GetStateHolder(location)
    {
        for(var sStateId in _stateHolders)
        {
            if(_stateHolders[sStateId].Location == location )
                return _stateHolders[sStateId];
        }
        return null;
    }
    
    function GetStateHolders(status)
    {
        var oArr = null;
        for(var sStateId in _stateHolders)
        {
            if(_stateHolders[sStateId].Status == status )
            {
                if(oArr == null) oArr = new Array();
                oArr.push(_stateHolders[sStateId]);
            }
        }
        return oArr;
    }
    
    function RaiseOnClose(stateHolder)
    {
        try
        {
            if( _OnCloseDelagte != null )
            {
                _OnCloseDelagte(stateHolder);
                return true;
            }
        }
        catch(err)
        {/**/}
        return false;
    }
    
    function RaiseError(stateHolders)
    {
        try
        {
            if( _RaiseErrorDelagte != null )
            {
                _RaiseErrorDelagte(stateHolders);
                return true;
            }
        }
        catch(err)
        {/**/}
        return false;
    }
    
    function _CloseState(stateID)
    {
        var oStateHolder = _stateHolders[stateID];
        SOAP_CloseStateASync(stateID,oStateHolder.Parameters[0],"m_ASyncObject.CloseStateHandler");
        //RemoveStateHolder(stateID);
        //RaiseOnClose(stateID);
    }
}

function StateHolder(location,parameters,pageParameters,soapResult,stateXML,status,stateID)
{
    StateHolder.prototype.Location = location;
    StateHolder.prototype.Parameters = parameters;
    StateHolder.prototype.PageParameters = pageParameters;
    StateHolder.prototype.SOAPResult = soapResult;
    StateHolder.prototype.StateXML = stateXML;
    StateHolder.prototype.Status = status;
    StateHolder.prototype.StateID = stateID;
    
    this.Finalize = function()
    {
        this.Location = null;
        this.Parameters = null;
        this.PageParameters = null;
        this.SOAPResult = null;
        this.StateXML = null;
        this.Status = null;
        this.StateID = null;
    }
}

//var m_ASyncHandler = new ASyncHandler();
