<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    creationComplete="init()" width="680" height="409" viewSourceURL="srcview/index.html">
    
    <mx:Script>
        <![CDATA[
            import flash.net.registerClassAlias;
            import PhoneBook.PhoneBookEntryVO;
            import mx.events.ResizeEvent;
            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
            import mx.rpc.remoting.RemoteObject;
            import mx.containers.Canvas;
            
            private var phoneBookService:RemoteObject;
            
            private function init():void
            {
                // The line of code below is the essence of the example. The first argument is the name 
                // of the .NET class used in the example. The server-side class is mapped to the 
                // PhoneBookEntryVO class. When WebORB returns an instance of Weborb.Examples.PhoneBookRecord, 
                // as a result of the mapping below, Flex automatically maps it to PhoneBookEntryVO
                // There are two alternative approaches to this solution:
                // 1. Use RemoteObject attribute in PhoneBookEntryVO (it is commented out at the top of the class)
                // 2. Use class mapping in WebORB configuration file (see <classMappings> in weborb.config
                flash.net.registerClassAlias( "Weborb.Examples.PhoneBookRecord", PhoneBookEntryVO );
                
                phoneBookTabs.removeAllChildren();
                
                for( var i:Number = "A".charCodeAt( 0 ); i <= "Z".charCodeAt( 0 ); i++ )
                {
                    var tab:Roster = new Roster();
                    tab.percentWidth = 100;
                    tab.percentHeight = 100;
                    tab.label = String.fromCharCode( i );
                    tab.enabled = false;
                    phoneBookTabs.addChild( tab );
                }
                
                phoneBookService = new RemoteObject( "GenericDestination" );
                phoneBookService.source = "Weborb.Examples.PhoneBook";
                phoneBookService.addEventListener( FaultEvent.FAULT, gotError );
                phoneBookService.addEntry.addEventListener( ResultEvent.RESULT, newEntryAdded );
                phoneBookService.getEntries.addEventListener( ResultEvent.RESULT, gotEntries );
                phoneBookService.getEntries();
                firstNameField.setFocus();            
            }
            
            /*
            This function is called when a user clicks on the Add Entry button. The
            function creates an instance of the PhoneBookEntryVO object and sends to the
            remote service
            */
            private function addEntry():void
            {
                if( firstNameField.text.length == 0 || lastNameField.text.length == 0 || phoneNumberField.text.length == 0 )
                {
                    Alert.show( "All fields are required", "Missing form data" );
                    return;
                }
                
                var newEntry:PhoneBookEntryVO = new PhoneBookEntryVO();
                newEntry.firstName = firstNameField.text.charAt( 0 ).toUpperCase();
                
                if( firstNameField.text.length > 1 )
                    newEntry.firstName += firstNameField.text.substr( 1 );
                
                newEntry.lastName = lastNameField.text.charAt( 0 ).toUpperCase();
                
                if( lastNameField.text.length > 1 )
                    newEntry.lastName += lastNameField.text.substr( 1 );
                
                newEntry.phoneNumber = phoneNumberField.text;
                firstNameField.text = "";
                lastNameField.text = "";
                phoneNumberField.text = "";
                
                phoneBookService.addEntry( newEntry );
            }
            
            /*
            This is a callback from the remote method invocation when a new entry is added
            to the phonebook
            */
            private function newEntryAdded( result:ResultEvent ):void
            {
                var addedEntry:PhoneBookEntryVO = result.result as PhoneBookEntryVO;
                processEntry( addedEntry );
            }
            
            /*
            This is a callback for the remote invocation initiated in the init() method.
            The result argument contains a list of all PhoneBook entries accumulated thus far
            */
            private function gotEntries( result:ResultEvent ):void
            {
                if( result.result.length == 0 )
                {
                    var entry:PhoneBookEntryVO = new PhoneBookEntryVO();
                    entry.firstName = "Midnight";
                    entry.lastName = "Coders";
                    entry.phoneNumber = "972.342.6908";
                    phoneBookService.addEntry( entry );
                    return;                
                }
                
                for( var i:Number = 0; i < result.result.length; i++ )
                    processEntry( result.result[ i ] as PhoneBookEntryVO );
            }
            
            /*
            This is a general 'catch-all' callback for any error sent from the server
            */            
            private function gotError( fault:FaultEvent ):void
            {
                Alert.show( "Server reported an error - " + fault.fault.faultString );
            }
            
            private function processEntry( entry:PhoneBookEntryVO ):void
            {                
                // determine which tab to add the entry to
                var tabIndex:Number = entry.lastName.charCodeAt( 0 ) - "A".charCodeAt( 0 );

                if( tabIndex < 0 || tabIndex > 26 )
                {
                    Alert.show( "Sorry, cannot add entry for " + entry.firstName + ", " + entry.lastName + ". No tab to put it to", "Missing tab" );                
                    return;
                }

                var tab:Roster = phoneBookTabs.getChildAt( tabIndex ) as Roster;
                tab.enabled = true;
                tab.addPhoneBookEntry( entry );
                phoneBookTabs.selectedIndex = tabIndex;                
            }            
        ]]>
    </mx:Script>
    <mx:Panel x="10" y="10" width="661" height="386" layout="absolute" title="Client Server Class Mapping Example">
        <mx:Text x="6" y="10" text="Phone book:"/>
        <mx:TabNavigator id="phoneBookTabs" historyManagementEnabled="false" x="6" y="36" width="627" height="157">
            <mx:Canvas label="Tab 1" width="100%" height="100%">
            </mx:Canvas>
        </mx:TabNavigator>
        <mx:Canvas x="6" y="201" width="269" height="135" borderStyle="solid" cornerRadius="10">
            <mx:Text x="12" y="21" text="First name:"/>
            <mx:Text x="12" y="47" text="Last name:"/>
            <mx:Text x="12" y="73" text="Phone number:"/>
            <mx:TextInput x="114" y="19" width="140" backgroundColor="#b5cccb" borderStyle="solid" borderThickness="1" borderColor="#79aa98" id="firstNameField"/>
            <mx:TextInput x="114" y="45" width="140" backgroundColor="#b5cccb" borderStyle="solid" borderThickness="1" borderColor="#79aa98" id="lastNameField"/>
            <mx:TextInput x="114" y="71" width="140" backgroundColor="#b5cccb" borderStyle="solid" borderThickness="1" borderColor="#79aa98" id="phoneNumberField"/>
            <mx:Button x="171" y="101" label="Add Entry" click="addEntry()"/>
        </mx:Canvas>
        <mx:Text x="17" y="194" text="New Entry" opaqueBackground="0xffffff"/>
        <mx:TextArea x="311" y="210" width="322" height="113" fontSize="16" editable="false" borderStyle="none">
            <mx:text>Add a new entry. It will be stored on the server and then returned back to the client. Each entry shows up in the corresponding tab (based on the first letter of the last name)</mx:text>
        </mx:TextArea>
    </mx:Panel>
    
</mx:Application>