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

package mx.accessibility
{

import flash.accessibility.Accessibility;
import flash.display.DisplayObject;
import flash.events.Event;
import mx.accessibility.AccConst;
import mx.containers.Accordion;
import mx.containers.accordionClasses.AccordionHeader;
import mx.controls.Button;
import mx.core.UIComponent;
import mx.core.mx_internal;

use namespace mx_internal;

/**
 *  AccordionHeaderAccImpl is a subclass of AccessibilityImplementation
 *  which implements accessibility for the AccordionHeader class.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class AccordionHeaderAccImpl extends AccImpl
{
    include "../core/Version.as";

	//--------------------------------------------------------------------------
	//
	//  Class constants
	//
	//--------------------------------------------------------------------------

	//--------------------------------------------------------------------------
	//
	//  Class methods
	//
	//--------------------------------------------------------------------------

	/**
	 *  Enables accessibility in the AccordionHeader class.
	 * 
	 *  <p>This method is called by application startup code
	 *  that is autogenerated by the MXML compiler.
	 *  Afterwards, when instances of AccordionHeader are initialized,
	 *  their <code>accessibilityImplementation</code> property
	 *  will be set to an instance of this class.</p>
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public static function enableAccessibility():void
	{
		AccordionHeader.createAccessibilityImplementation =
			createAccessibilityImplementation;
	}

	/**
	 *  @private
	 *  Creates an AccordionHeader's AccessibilityImplementation object.
	 *  This method is called from UIComponent's
	 *  initializeAccessibility() method.
	 */
	mx_internal static function createAccessibilityImplementation(
								component:UIComponent):void
	{
		component.accessibilityImplementation =
			new AccordionHeaderAccImpl(component);
	}

	//--------------------------------------------------------------------------
	//
	//  Constructor
	//
	//--------------------------------------------------------------------------

	/**
	 *  Constructor.
	 *
	 *  @param master The UIComponent instance that this AccImpl instance
	 *  is making accessible.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function AccordionHeaderAccImpl(master:UIComponent)
	{
		super(master);
		
		role = AccConst.ROLE_SYSTEM_PAGETAB;

		master.parent.addEventListener("change", eventHandler);
		master.addEventListener("removed", removedHandler);
	}

	//--------------------------------------------------------------------------
	//
	//  Overridden properties: AccImpl
	//
	//--------------------------------------------------------------------------

	//----------------------------------
	//  eventsToHandle
	//----------------------------------

	/**
	 *  @private
	 *	Array of events that we should listen for from the master component.
	 */
	override protected function get eventsToHandle():Array
	{
		return super.eventsToHandle.concat([ "focusDraw" ]);
	}
	 
	//--------------------------------------------------------------------------
	//
	//  Overridden methods: AccessibilityImplementation
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 *  IAccessible method for returning the state of Tab selected.
	 *
	 *  @param childID uint
	 *
	 *  @return State uint
	 */
	override public function get_accState(childID:uint):uint
	{
		var accState:uint = getState(childID);
		
		var accordion:Accordion = Accordion(master.parent);
		
		if (accordion.enabled)
		{
			accState |= AccConst.STATE_SYSTEM_SELECTABLE;
		
			if (Button(master).selected)
				accState |= AccConst.STATE_SYSTEM_SELECTED;
				
			var index:int = accordion.focusedIndex;
			if (index >= 0 && master == accordion.getHeaderAt(index))
				accState |= AccConst.STATE_SYSTEM_FOCUSED;
		}					 
		else
			accState |= AccConst.STATE_SYSTEM_UNAVAILABLE;

		return accState;
	}

	/**
	 *  @private
	 *  IAccessible method for returning the Default Action.
	 *
	 *  @param childID uint
	 *
	 *  @return name of default action.
	 */
	override public function get_accDefaultAction(childID:uint):String
	{
		return "Switch";
	}

	//--------------------------------------------------------------------------
	//
	//  Overridden methods: AccImpl
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 *  method for returning the name of the Tab
	 *  which is spoken out by the screen reader.
	 *
	 *  @param childID uint
	 *
	 *  @return Name String
	 */
	override protected function getName(childID:uint):String
	{
		var tab:Button = Button(master);
		
		if (childID > 0)
		{
			var parentAccordion:Accordion = Accordion(master.parent);
			tab = parentAccordion.getHeaderAt(parentAccordion.focusedIndex);
		}

		return tab.label;
	}

	//--------------------------------------------------------------------------
	//
	//  Overridden event handlers: AccImpl
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 *  Override the generic event handler.
	 *  All AccImpl must implement this to listen for events
	 *  from its master component. 
	 */
	override protected function eventHandler(event:Event):void
	{
		// Let AccImpl class handle the events
		// that all accessible UIComponents understand.
		$eventHandler(event);
		
		var index:int;

		switch (event.type)
		{
			case "focusDraw":
			{
				// event.currentTarget here is the AccordionHeader (a/k/a 'master')
				index = Accordion(event.currentTarget.parent).focusedIndex;
				if (index >= 0 && master == Accordion(event.currentTarget.parent).getHeaderAt(index))
				{
					Accessibility.sendEvent(DisplayObject(event.currentTarget), index + 1,
											AccConst.EVENT_OBJECT_FOCUS, true);
				}
				break;
			}

			case "change":
			{
				// event.currentTarget here is the Accordion (a/k/a 'master.parent')
				index = Accordion(event.currentTarget).selectedIndex;
				if (index >= 0 && master == Accordion(event.currentTarget).getHeaderAt(index))
				{
					Accessibility.sendEvent(master, index + 1,
											AccConst.EVENT_OBJECT_SELECTION, true);
				}
				break;
			}
		}
	}
	
	/**
	 *  @private
	 *  Remove the change handler on the accordion that was causing this to stick around in memory 
	 *  and cause RTE. Also remove self.
	 */
	protected function removedHandler(event:Event):void
	{
		master.parent.removeEventListener("change", eventHandler);
		master.removeEventListener("removed", removedHandler);
	}

}

}
