<?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/List/Integration/"  xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" testSWF="ListMain_spark.mxml">
    <mx:Script>
    <![CDATA[
    public static function init(o:DisplayObject):void
    {
    }
    ]]>
    </mx:Script>
    <mx:Metadata>
    <![CDATA[
        [Mixin]
    ]]>
    </mx:Metadata>
    <mx:Script>
    <![CDATA[
    import mx.styles.StyleManager;
    import mx.managers.SystemManager;
    import mx.managers.ToolTipManager;
    import mx.controls.Alert;
    import mx.controls.PopUpMenuButton;
    import mx.controls.ToolTip;
    private var myPUMB:PopUpMenuButton;

    public function addItems(n:int):void{
       for(var i:int=0;i<n;i++)  {
          var obj:Object={slno:i,name:"Added Item"+String(i),age:100+i}
          application.mybox.mylist.dataProvider.addItem(obj);
       }
    }

    public function addPUMB():void{
       myPUMB = new  PopUpMenuButton();
       myPUMB.dataProvider = ['one', 'two', 'gggg', 'yyyy', 'jjjj', 'pppp', 'qqqq'];
       application.mybox.addChild(myPUMB);
    }

    public function addLongItem():void{
          var obj:Object={slno:0,name:"Added Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong Item",age:100}
          application.mybox.mylist.dataProvider.addItemAt(obj,3);
    }

    private function toolTipValue():String
    {
        return application.mybox.mylist.selectedItem.age;
    }



      public var myTip:ToolTip;

      private function createBigTip( event:Event ):void {
         var s:String = "This is a custom ToolTip."
         myTip = ToolTipManager.createToolTip(s,10,10) as ToolTip;
         myTip.setStyle("backgroundColor",0xFFCC00);
         myTip.width = 250;
         myTip.height = 50;
      }

      private function destroyBigTip():void {
         ToolTipManager.destroyToolTip(myTip);
      }

    ]]>
    </mx:Script>

      <testCases>

    <TestCase testID="Spark_list_integration_bugs_156053" keywords="[list, bugs, 156053]">
          <setup>
           <ResetComponent target="mybox" className="ListComp" waitEvent="updateComplete" waitTarget="mybox"/>
           <RunCode code="addPUMB()" />
         </setup>
        <body>
          <SetProperty target="mybox.mylist" propertyName="selectedIndex" value= "1"/>
         </body>
    </TestCase>

    <TestCase testID="Spark_list_toolTip_enabled" keywords="[list, toolTip]">
          <setup>
           <ResetComponent target="mybox" className="ListComp" waitEvent="updateComplete" waitTarget="mybox"/>
           <SetProperty target="mybox.mylist" propertyName="toolTip" value="tip"/>
         </setup>
        <body>

              <DispatchMouseEvent type="mouseOver" target="mybox.mylist" localX="10" localY="10" waitEvent="mouseOver" waitTarget="mybox.mylist"/>
          <AssertEvent target="mybox.mylist" eventName="toolTipShow" eventClass="mx.events::ToolTipEvent" />
          <AssertEvent target="mybox.mylist" eventName="toolTipShown" eventClass="mx.events::ToolTipEvent" />
            </body>
    </TestCase>

    <TestCase testID="Spark_list_toolTip_disabled" keywords="[list, toolTip]">
          <setup>
           <ResetComponent target="mybox" className="ListComp" waitEvent="updateComplete" waitTarget="mybox"/>
           <SetProperty target="mybox.mylist" propertyName="toolTip" value="mytip"/>
           <RunCode code = "ToolTipManager.enabled = false;" />
         </setup>
        <body>
              <DispatchMouseEvent type="mouseOver" target="mybox.mylist" localX="10" localY="10" waitEvent="mouseOver" waitTarget="mybox.mylist"/>
          <CompareBitmap target="mybox.mylist" url="../Integration/Baselines/list_toolTip_disabled_spark.png"  />
          <RunCode code = "ToolTipManager.enabled = true;" />
          <DispatchMouseEvent type="mouseOver" target="mybox.mylist" localX="20" localY="10" waitEvent="mouseOver" waitTarget="mybox.mylist"/>
          <AssertEvent target="mybox.mylist" eventName="toolTipShow" eventClass="mx.events::ToolTipEvent" />
          <AssertEvent target="mybox.mylist" eventName="toolTipShown" eventClass="mx.events::ToolTipEvent" />
        </body>
    </TestCase>

    <TestCase testID="Spark_list_toolTip_dynamic" keywords="[list, toolTip]">
          <setup>
           <ResetComponent target="mybox" className="ListComp" waitEvent="updateComplete" waitTarget="mybox"/>
           <SetProperty target="mybox.mylist" propertyName="selectedIndex" value= "1"/>
           <SetProperty target="mybox.mylist" propertyName="toolTip" valueExpression="value=toolTipValue(); "/>
         </setup>
        <body>
              <DispatchMouseEvent type="mouseOver" target="mybox.mylist" localX="10" localY="10" waitEvent="mouseOver" waitTarget="mybox.mylist"/>
          <AssertEvent target="mybox.mylist" eventName="toolTipShow" eventClass="mx.events::ToolTipEvent" />
          <AssertPropertyValue target="mybox.mylist" propertyName="toolTip" value="21" />
      </body>
    </TestCase>

    <TestCase testID="Spark_list_toolTip_dynamic_custom" keywords="[list, toolTip]">
          <setup>
           <ResetComponent target="mybox" className="ListComp" waitEvent="updateComplete" waitTarget="mybox"/>
           <RunCode code="application.mybox.mylist.addEventListener(MouseEvent.CLICK, createBigTip);" />

         </setup>
        <body>
              <DispatchMouseClickEvent target="mybox.mylist" localX="10" localY="10" waitEvent="itemClick" waitTarget="mybox.mylist"/>
              <WaitForEffectsToEnd />
              <AssertPropertyValue target="script:myTip" propertyName="text" value="This is a custom ToolTip." />
          <AssertPropertyValue target="script:myTip" propertyName="width" value="250" />
          <AssertPropertyValue target="script:myTip" propertyName="height" value="50" />
          <AssertStyleValue target="script:myTip" styleName="backgroundColor" value="0xFFCC00" />
          <RunCode code="destroyBigTip();" />
      </body>
    </TestCase>

    </testCases>
</UnitTester>
