<?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.

-->
<UnitTester testDir="components/DataGrid/DataGrid_HaloSkin/Styles/"  xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" testSWF="DataGridMain_halo.mxml">

	<!-- this set of lines form a template that must be in each unit test -->
	<mx:Script>
	<![CDATA[
	public static function init(o:DisplayObject):void
	{
	}					
	]]>
	</mx:Script>
	<mx:Metadata>
	<![CDATA[
		[Mixin]
	]]>
	</mx:Metadata>	
	<!-- end of set of lines that must be in each unit test -->

	<mx:Script>
	<![CDATA[
	import mx.controls.DateChooser;
	import mx.controls.DataGrid;
	import mx.containers.Canvas;
	import mx.styles.StyleManager;
	import mx.managers.SystemManager;
	public var mydatagrid:DataGrid
	public var testgrid:DataGrid
	public var mybox:Canvas;
	public function genericCleanUp():void
	{
	 mydatagrid= stringToObject ("mydatagrid") as DataGrid;

	 mybox = stringToObject ("box") as Canvas;
	 mybox = new Canvas();
		mydatagrid = new DataGrid();

		
		application.startIt();
		
	}
	public function addItems():void
	{
	   for(var i:int=0;i<15;i++)
	   {
	      var obj:Object={col1:'one'+i,col2:i,col3:'three'+i}
	      application.mydatagrid.dataProvider.addItem(obj);
	   }
        }
        public function setAIcolors():void
        {
            application.mydatagrid.setStyle("alternatingItemColors",[0xFFCC00,0x00FF00]);
        }
        public function setBg():void
        {
            application.mydatagrid.setStyle("backgroundColor",0xFF0000);
        }
        public function setFF():void
        {
        
           application.mydatagrid.setStyle("fontFamily","Arial");
        }
        public function startApp():void
        {
          application.startIt();
        }
        //Notes to self
        //SelectionDuration is getter setter check, revisit.
	]]>
	</mx:Script>
	
	<testCases>
	             
		       <TestCase testID="style_alternatingitemcolors_halo" keywords="[DataGrid, alternatingitemcolors]">
				     <body>
				     	          <ResetComponent target="mydatagrid" className="mx.controls.DataGrid" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <RunCode code="startApp()"/>
						  <SetStyle target="mydatagrid" styleName="alternatingItemColors" value="['#FFCC00','#CC0000']" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <CompareBitmap target="mydatagrid" url="../Styles/Baselines/datagrid_alternatingitemcolors.png" />
				     </body>
		       </TestCase>
		       <TestCase testID="style_paddingBottom_halo" keywords="[DataGrid, paddingbottom]">
				     <body>
				     <ResetComponent target="mydatagrid" className="mx.controls.DataGrid" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						 <RunCode code="startApp()"/>
						 <SetStyle target="mydatagrid" styleName="paddingBottom" value="12" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <CompareBitmap target="mydatagrid" url="../Styles/Baselines/datagrid_paddingbottom.png" />
				     </body>
		       </TestCase>
		        <TestCase testID="style_paddingtop_halo" keywords="[DataGrid, paddingTop]">
				     <body>
				     <ResetComponent target="mydatagrid" className="mx.controls.DataGrid" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						<RunCode code="startApp()"/>
						<SetStyle target="mydatagrid" styleName="paddingTop" value="12" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <CompareBitmap target="mydatagrid" url="../Styles/Baselines/datagrid_paddingTop.png" />
				     </body>
		       </TestCase>
		        <TestCase testID="style_paddingleft_halo" keywords="[DataGrid, paddingLeft]">
				     <body>
				     <ResetComponent target="mydatagrid" className="mx.controls.DataGrid" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						 <RunCode code="startApp()"/>
						 <SetStyle target="mydatagrid" styleName="paddingLeft" value="12" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <CompareBitmap target="mydatagrid" url="../Styles/Baselines/datagrid_paddingLeft.png" />
				     </body>
		       </TestCase>
		        <TestCase testID="style_paddingright_halo" keywords="[DataGrid, paddingRight]">
				     <body>
				     <ResetComponent target="mydatagrid" className="mx.controls.DataGrid" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <RunCode code="startApp()"/>
						  <SetStyle target="mydatagrid" styleName="paddingRight" value="12" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <CompareBitmap target="mydatagrid" url="../Styles/Baselines/datagrid_paddingRight.png" />
				     </body>
		       </TestCase>
		     		        
		       <TestCase testID="style_userollover_halo" keywords="[DataGrid, useRollOver]">
				     <body>
				     <ResetComponent target="mydatagrid" className="mx.controls.DataGrid" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <RunCode code="startApp()"/>
						  <SetStyle target="mydatagrid" styleName="useRollOver" value="false" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <DispatchMouseEvent type="mouseOver" target="mydatagrid" localX="250" localY="90"/>
						  <CompareBitmap target="mydatagrid" url="../Styles/Baselines/datagrid_userollover.png" />
				     </body>
		       </TestCase>
		       
		       <TestCase testID="style_verticalalign_top_halo" keywords="[DataGrid, verticalAlign_top]">
				     <body>
				     <ResetComponent target="mydatagrid" className="mx.controls.DataGrid" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <RunCode code="startApp()"/>
						  <SetStyle target="mydatagrid" styleName="verticalAlign" value="top" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <CompareBitmap target="mydatagrid" url="../Styles/Baselines/datagrid_verticalalign_top.png" />
				     </body>
		       </TestCase>
	                  
	                <TestCase testID="style_verticalalign_bottom1_halo" keywords="[DataGrid, verticalAlign_bottom]">
				     <body>
				     <ResetComponent target="mydatagrid" className="mx.controls.DataGrid" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <RunCode code="startApp()"/>
						  <SetStyle target="mydatagrid" styleName="verticalAlign" value="bottom" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <CompareBitmap target="mydatagrid" url="../Styles/Baselines/datagrid_verticalalign_bottom.png" />
				     </body>
		       </TestCase> 
	
                       <TestCase testID="style_verticalalign_bottom2_halo" keywords="[DataGrid, selectionDuration]">
				     <body>
				     <ResetComponent target="mydatagrid" className="mx.controls.DataGrid" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						  <RunCode code="startApp()"/>
						  <SetStyle target="mydatagrid" styleName="selectionDuration" value="100" waitTarget="mydatagrid" waitEvent="updateComplete"/>
						   <AssertStyleValue styleName="selectionDuration" value="100" target="mydatagrid"/>
				     </body>
		       </TestCase> 
	</testCases>                
	     
</UnitTester>
