<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" viewSourceURL="srcview/index.html">
    <mx:Style>
        Application{background-color:#000000;}
        ControlBar{padding-left:10px; padding-top:4px; padding-right:10px; padding-bottom:4px; }
        Label{color:#ffffff;}
        TextArea{font-family: Consolas, Courier, monospace; font-size:12px}
    </mx:Style>
    <mx:Script>
        <![CDATA[
            import mx.rpc.AsyncToken;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
            import mx.rpc.remoting.mxml.RemoteObject;
            
            [Bindable]
            private var debugText:String;
            
            private var testQueue:Array;
            
            private var servicesQueue:Dictionary;
            
            private var currentTestName:String;
            
            public static const SERVICE_ERROR_NAME:String = 'SX_Service_Test_Error';
            
            // send integer
            public static const SEND_INT:String = 'sendInteger'; 
            // send boolean
            public static const SEND_BOOL:String = 'sendBoolean'; 
            // send strinc latin
            public static const SEND_STR_LAT:String = 'sendStringLatin';
            // send string cyrillic
            public static const SEND_STR_CYR:String = 'sendStringCyrillic';
            // send date
            public static const SEND_DATE:String = 'sendDate';
            // send array
            public static const SEND_ARRAY:String = 'sendArray';
            // send object
            public static const SEND_OBJ:String = 'sendObject';
            // send custom object (mapped)
            public static const SEND_VO:String = 'sendCustomObject';
            
            
            // receive integer
            public static const RECEIVE_INT:String = 'receiveInteger'; 
            // receive boolean
            public static const RECEIVE_BOOL:String = 'receiveBoolean'; 
            // receive strinc latin
            public static const RECEIVE_STR_LAT:String = 'receiveStringLatin';
            // receive string cyrillic
            public static const RECEIVE_STR_CYR:String = 'receiveStringCyrillic';
            // receive date
            public static const RECEIVE_DATE:String = 'receiveDate';
            // receive array
            public static const RECEIVE_ARRAY:String = 'receiveArray';
            // receive object
            public static const RECEIVE_OBJ:String = 'receiveObject';
            // receive custom object (mapped)
            public static const RECEIVE_VO:String = 'receiveCustomObject';
            // response thrown an exception
            public static const RECEIVE_ERROR:String = 'receiveError';
            
            private function callNext():void
            {
                var call:AsyncToken;
                currentTestName = testQueue.pop();    
                
                if(null == currentTestName)    return;
                
                var param:* = createParamByName(currentTestName);
                            
                if(undefined !== param)
                {
                    debugText += 'CALL: ' + txtSource.text + '.' + currentTestName + '( ' + param + ' )\n';    
                    call = amfTest.getOperation(currentTestName).send( createParamByName(currentTestName) );
                }
                else
                {
                    debugText += 'CALL: ' + txtSource.text + '.' + currentTestName + '()\n';
                    call = amfTest.getOperation(currentTestName).send( );
                }                    
                    
                servicesQueue[currentTestName] = call;
            }
            
            private function createParamByName(name:String):*
            {
                switch(name)
                {
                    case(SEND_INT):         return Math.pow(2, 32); 
                    case(SEND_BOOL):    return true; 
                    case(SEND_STR_LAT):    return "Only latin characters";
                    case(SEND_STR_CYR):    return 'Кириллится?';
                    case(SEND_DATE):    return new Date();
                    case(SEND_ARRAY):    return [1, 2, 3, 'Qwe', 'Rty'];
                    case(SEND_OBJ):        return { prop1 : 'val1', prop2 : ['a', 'b', 'c']};
                    case(SEND_VO):        return { prop1 : 'val1', prop2 : ['a', 'b', 'c']};
                    default:            return undefined;
                }
            }
            
            private function resultHandler(event:ResultEvent):void
            {
                debugText += '<font color="#009900">OK: ' + resultToString(event.result) + '</font>\n';
                callNext();
            }

            private function faultHandler(event:FaultEvent):void
            {
                if(SERVICE_ERROR_NAME == event.fault.faultString)
                {
                    debugText += '<font color="#009900">OK: service error throws successfully</font>\n';
                    callNext();
                }    
                else
                    debugText += '<font color="#FF0000">ERROR: ' + event.fault.faultString + ' ' + event.fault.faultDetail + '</font>\n';    
            }
            
            private function startTest():void
            {
                testQueue = [];

                testQueue.push(RECEIVE_ERROR);
                testQueue.push(RECEIVE_STR_CYR);
                testQueue.push(SEND_STR_CYR);
                testQueue.push(RECEIVE_STR_LAT);
                testQueue.push(SEND_STR_LAT);
                testQueue.push(RECEIVE_VO);
                testQueue.push(SEND_VO);                
                testQueue.push(RECEIVE_DATE);                
                testQueue.push(SEND_DATE);
                testQueue.push(RECEIVE_OBJ);
                testQueue.push(SEND_OBJ);
                testQueue.push(RECEIVE_ARRAY);
                testQueue.push(SEND_ARRAY);                
                testQueue.push(RECEIVE_BOOL);
                testQueue.push(SEND_BOOL); 
                testQueue.push(RECEIVE_INT);
                testQueue.push(SEND_INT); 
                                                
                servicesQueue = new Dictionary;
                
                debugText = '';
                
                callNext();
            }
                
            private function resultToString(value:*):String
            {
                if (null === value) 
                    return 'null';
                else if('object' == typeof(value))
                {
                    var ret:String = '{';
                    for(var p:Object in value)
                    {
                        ret += p + ':\'' + value[p] + '\', ';    
                    }
                    return ret.replace(/, $/, '') + '}';
                }
                else
                    return value.toString(); 
            }        
        ]]>
    </mx:Script>
    <mx:VBox width="100%" height="100%">
        <mx:ControlBar>
            <mx:Button label="Start" click="startTest()" />
            <mx:Label text="Gateway"/>
            <mx:TextInput  text="/amf-benchmark/amfphp/gateway.php" id="txtGateway"/>
            <mx:Label text="Source"/>
            <mx:TextInput  text="SX_Service_Test" id="txtSource"/>
        </mx:ControlBar>
        <mx:TextArea width="100%" height="100%"  htmlText="{debugText}" />    
    </mx:VBox>
    <mx:RemoteObject 
        source="{txtSource.text}"
        destination="none" 
        id="amfTest" endpoint="{txtGateway.text}" 
        result="resultHandler(event)" fault="faultHandler(event)"/>
</mx:Application>