<?xml version="1.0" encoding="utf-8"?>
<!--

  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" 
			   minWidth="955" minHeight="850"
			   creationComplete="employeeService.getEmployees()" 
			   xmlns:components="components.*">
	
	<!-- Exercise 3.04b: Passing data to the server with the WebService class -->
	
	<!-- Styles ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
	
	<fx:Style source="Styles.css"/>
	
	<!-- Script ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
	
	<fx:Script>
		<![CDATA[
			import events.VehicleRequestEvent;
			
			import mx.collections.ArrayCollection;
			import mx.controls.Alert;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
			
			import valueObjects.Employee;
			
			// variable declarations ------------------------------------
			
			[Bindable]
			private var employees:ArrayCollection = new ArrayCollection();
			
			// getter/setters -------------------------------------------
			
			
			// helper methods -------------------------------------------
			
			
			// event handlers -------------------------------------------
			
			protected function employeeService_resultHandler(event:ResultEvent):void
			{
				var employeeData:ArrayCollection = event.result as ArrayCollection;
				var employee:Employee;
				
				for each (var emp:Object in employeeData) 
				{
					employee = new Employee();
					employee.firstName = emp.FIRSTNAME;
					employee.lastName = emp.LASTNAME;
					employee.id = emp.ID;
					employee.title = emp.TITLE;
					employee.email = emp.EMAIL;
					employee.managerID = emp.MANAGERID;
					employee.department = emp.DEPARTMENT;
					employee.location = emp.LOCATION;
					employee.deskLocation = emp.DESKLOCATION;
					employee.city = emp.CITY;
					employee.state = emp.STATE;
					employee.countryCode = emp.COUNTRYCODE;
					employee.postalCode = emp.POSTALCODE;
					employee.directDial = emp.DIRECTDIAL;
					employee.hireDate = emp.HIREDATE;
					employee.evaluation = emp.EVALUATION;
					employee.phone = emp.PHONE;
					employees.addItem(employee);
				}
				
			}
			
			protected function employeeService_faultHandler(event:FaultEvent):void
			{
				Alert.show(event.fault.faultString,"Fault Information");	
			}
			
			protected function vehiclerequestform1_vehicleRequestEventHandler(event:VehicleRequestEvent):void
			{
				vehicleService.addVehicleRequest(event.vehicleRequestData);
			}
			
			protected function vehicleService_resultHandler(event:ResultEvent):void
			{
				if(event.result.id)
				{
					Alert.show("The request was submitted. The record id is " + event.result.id);
				}
			}
			
			protected function vehicleService_faultHandler(event:FaultEvent):void
			{
				Alert.show(event.fault.faultString,"Fault Information");
			}
			
		]]>
	</fx:Script>
	
	<!-- Declarations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
	
	<fx:Declarations>

		<s:WebService id="employeeService"
					  wsdl="http://www.adobetes.com/f45iaw100/remoteData/EmployeeData.cfc?wsdl"
					  result="employeeService_resultHandler(event)"
					  fault="employeeService_faultHandler(event)"/>
		
		<s:WebService id="vehicleService" 
					  wsdl="http://www.adobetes.com/f45iaw100/remoteData/vehicleRequestData.cfc?wsdl"
					  result="vehicleService_resultHandler(event)"
					  fault="vehicleService_faultHandler(event)"/>			
		
	</fx:Declarations>
	
	<!-- UI components ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
	
	<s:Label x="10" y="34" 
			 width="690" height="40" 
			 text="Employee Portal: Vehicle Request Form"
			 styleName="titleHeader"/>
	
	<components:VehicleRequestForm employees="{employees}"
								   vehicleRequestEvent="vehiclerequestform1_vehicleRequestEventHandler(event)"/>
	
</s:Application>
