<?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.
-->
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
		addedToStage="onAddedToStage()" removedFromStage="onRemovedFromStage()"	 horizontalScrollPolicy="off" verticalScrollPolicy="off" width="1200">
	<mx:Metadata>
		<!-- event generated by this component -->
		<!-- FOR NOW this is a Flex only event. This is OK because its UI only in Flow. -->
		[Event(name="scroll", type="mx.events.ScrollEvent")]
	</mx:Metadata>
	<mx:Script>
		<![CDATA[
			import mx.messaging.config.ConfigMap;
			import flashx.textLayout.elements.Configuration;
			import flashx.textLayout.container.ContainerController;
			import flashx.textLayout.formats.BlockProgression;
			import mx.events.ScrollEventDetail;
			import mx.events.ScrollEventDirection;
			import mx.events.ScrollEvent;
			import flashx.textLayout.edit.ElementRange;
			import flashx.textLayout.elements.TextFlow;
			import flashx.textLayout.compose.IFlowComposer;
			import flashx.textLayout.container.ScrollPolicy;
			
			
		    private var onStage:Boolean = false;
    		private var addedFrameEventListener:Boolean = false;
    		
 			[Bindable]
    		public var scrollList:Array = ["Line", "Page", "Off"];
    		
    		public function update(range:ElementRange):void
    		{
    			
    		}
    		
	  		private function doScroll(detail:String, position:Number, direction:String, delta:Number):void
	 		{
	 			dispatchEvent(new ScrollEvent(ScrollEvent.SCROLL, false, false, detail, position, direction, delta));
	 			
	 			/*
	 			if (!_activeFlow || !_activeFlow.flowComposer || _activeFlow.flowComposer.numControllers == 0)
	 				return;
	 			
	 			var controller:ContainerController = _activeFlow.flowComposer.getControllerAt(_activeFlow.flowComposer.numControllers - 1);
	 			
	 			if (!isNaN(delta))
	 			{
	 				
	 				if (detail == ScrollEventDetail.LINE_UP || detail == ScrollEventDetail.LINE_DOWN)
	 				{
		 				if (_activeFlow.computedFormat.blockProgression == BlockProgression.RL)
		 					controller.horizontalScrollPosition += controller.getScrollDelta(delta);
		 				else
		 					controller.verticalScrollPosition += controller.getScrollDelta(delta);
	 				}
		 			else switch (direction)
		 			{
		 				case ScrollEventDirection.HORIZONTAL:	controller.horizontalScrollPosition += delta;
		 														break;
		 				case ScrollEventDirection.VERTICAL:		controller.verticalScrollPosition += delta;
		 														break;
		 			}
		 		}
		 		else if (!isNaN(position))
		 			switch (direction)
		 			{
		 				case ScrollEventDirection.HORIZONTAL:	controller.horizontalScrollPosition = position;
		 														break;
		 				case ScrollEventDirection.VERTICAL:		controller.verticalScrollPosition = position;
		 														break;
		 			}
		 		*/
	 		}
 
 
			private function onAddedToStage():void
			{
				// the dataProviders aren't set up yet - delay to the frame
				onStage = true;
				if (!addedFrameEventListener)
				{
					addedFrameEventListener = true;
					addEventListener("enterFrame",onEnterFrame);
				}
			}
		
			private function onEnterFrame(p:Event):void
			{
				this.removeEventListener("enterFrame",onEnterFrame);
				addedFrameEventListener = false;

				updateScrollSettings();
			}
	
			private function onRemovedFromStage():void
			{
				onStage = false;
			}
			
			private function updateScrollSettings():void
			{
				if (_activeFlow && _activeFlow.flowComposer && _activeFlow.flowComposer.numControllers)
				{
					// TODO: multiple controllers?
					var firstController:ContainerController = _activeFlow.flowComposer.getControllerAt(0);
					xScroll.text = Math.floor(firstController.horizontalScrollPosition).toString();
					yScroll.text = Math.floor(firstController.verticalScrollPosition).toString();
					var contentBounds:Rectangle = firstController.getContentBounds();
					maxX.text = Math.floor(contentBounds.width).toString();
					maxY.text = Math.floor(contentBounds.height).toString();
					var textConfiguration:Configuration = Configuration(_activeFlow.configuration);
					DragDelay.text = String(textConfiguration.scrollDragDelay);
					DragPixels.text = String(textConfiguration.scrollDragPixels);
					PagePercent.text = String(textConfiguration.scrollPagePercentage);
					MouseWheelMultiplier.text = String(textConfiguration.scrollMouseWheelMultiplier);
				}
			}
			
			private function updateScrollOnOff():void
			{
			
				if (_activeFlow && _activeFlow.flowComposer && _activeFlow.flowComposer.numControllers > 0)
				{
					var scrollingOn:Boolean;
					var newScrollingOn:Boolean;
					var flowComposer:IFlowComposer = _activeFlow.flowComposer;
					var controller:ContainerController = flowComposer.getControllerAt(flowComposer.numControllers - 1);
					var textConfiguration:Configuration = Configuration(_activeFlow.configuration);
					if (_activeFlow.computedFormat.blockProgression == BlockProgression.TB)
					{
						scrollingOn = (controller.verticalScrollPolicy != ScrollPolicy.OFF);
						newScrollingOn = scrollByAmount.selectedLabel != "Off";
						if (scrollingOn != newScrollingOn)
							controller.verticalScrollPolicy = newScrollingOn ? ScrollPolicy.ON : ScrollPolicy.OFF;
					}
					else
					{
						scrollingOn = (controller.horizontalScrollPolicy != ScrollPolicy.OFF);
						newScrollingOn = scrollByAmount.selectedLabel != "Off";
						if (scrollingOn != newScrollingOn)
							controller.horizontalScrollPolicy = newScrollingOn ? ScrollPolicy.ON : ScrollPolicy.OFF;
					}
				}
			}
			
			private function updateScrollDragDelay():void
			{
				if (_activeFlow && _activeFlow.configuration && (DragDelay.text != ""))
				{
					var textConfiguration:Configuration = Configuration(_activeFlow.configuration);
					textConfiguration.scrollDragDelay = Number(DragDelay.text);
				}
			}

			private function updateScrollDragPixels():void
			{
				if (_activeFlow && _activeFlow.configuration && (DragPixels.text != ""))
				{
					var textConfiguration:Configuration = Configuration(_activeFlow.configuration);
					textConfiguration.scrollDragPixels = Number(DragPixels.text);
				}
			}

			private function updateScrollPagePercent():void
			{
				if (_activeFlow && _activeFlow.configuration && (PagePercent.text != ""))
				{
					var textConfiguration:Configuration = Configuration(_activeFlow.configuration);
					textConfiguration.scrollPagePercentage = Number(PagePercent.text);
				}
			}

			private function updateScrollMouseWheelMultiplier():void
			{
				if (_activeFlow && _activeFlow.configuration && (MouseWheelMultiplier.text != ""))
				{
					var textConfiguration:Configuration = Configuration(_activeFlow.configuration);
					textConfiguration.scrollMouseWheelMultiplier = Number(MouseWheelMultiplier.text);
				}
			}

			private var _activeFlow:TextFlow = null;
			public function get activeFlow():TextFlow
			{
				return _activeFlow;
			}
			
			public function set activeFlow(t:TextFlow):void
			{
				_activeFlow = t;
			}
			
			public function scrollTo(x:Number, y:Number):void
			{
				var detail:String;
				var delta:Number;
				doScroll(detail, x, ScrollEventDirection.HORIZONTAL, delta);
				doScroll(detail, y, ScrollEventDirection.VERTICAL, delta);
				updateScrollSettings();
			}			
			
			public function scroll(button:Button):void
			{
				var direction:String;
				var detail:String;
				var position:Number;
				var delta:Number;
				var scrollPercent:Number;
				var dirVal:Number;
				
 				if (_activeFlow.flowComposer && _activeFlow.flowComposer.numControllers)
				{
					// TODO: multiple controllers?
					var firstController:ContainerController = _activeFlow.flowComposer.getControllerAt(0);
					var textConfiguration:Configuration = Configuration(_activeFlow.configuration);
					scrollPercent = textConfiguration.scrollPagePercentage;
					
					switch(button)
					{
						case leftScroll:
							dirVal = -1;	
							direction = ScrollEventDirection.HORIZONTAL;							
							break;
						case rightScroll:	
							dirVal = 1;	
							direction = ScrollEventDirection.HORIZONTAL;							
							break;
						case upScroll:
							dirVal = -1;	
							direction = ScrollEventDirection.VERTICAL;
							break;							
						case downScroll:	
							dirVal = 1;	
							direction = ScrollEventDirection.VERTICAL;
							break;
					}	
																									
					delta = dirVal * ((direction == ScrollEventDirection.VERTICAL) ? (firstController.compositionHeight * scrollPercent) : (firstController.compositionWidth * scrollPercent));

					var blockProgression:String = _activeFlow.computedFormat.blockProgression;
					if (scrollByAmount.selectedLabel == "Line") 
					{
						if (blockProgression == BlockProgression.TB && (button == upScroll || button == downScroll)) {
							delta = dirVal;
							detail = ScrollEventDetail.LINE_UP;
						}
						if (blockProgression == BlockProgression.RL && (button == leftScroll || button == rightScroll)) {
							delta = -dirVal;
							detail = ScrollEventDetail.LINE_UP;
						}
					}
					
					doScroll(detail, position, direction, delta);
					updateScrollSettings();
				}
			}
		]]>
	</mx:Script>
	<mx:HBox width="100%" horizontalAlign="left" verticalAlign="middle" horizontalGap="5">
		<mx:Button id="leftScroll" label="Left" autoRepeat="true" buttonDown="scroll(leftScroll)" width="48"/>
		<mx:Button id="rightScroll" label="Right" autoRepeat="true" buttonDown="scroll(rightScroll)" width="55"/>
		<mx:Button id="upScroll" label="Up" autoRepeat="true" buttonDown="scroll(upScroll)" width="40"/>
		<mx:Button id="downScroll" label="Down" autoRepeat="true" buttonDown="scroll(downScroll)" width="60"/>
		<mx:ComboBox id="scrollByAmount" dataProvider="{scrollList}" selectedIndex="0" change="updateScrollOnOff()"/>
		<mx:Label text="Page%" fontWeight="bold" width="47"/>
		<mx:TextInput id="PagePercent" width="45" change="updateScrollPagePercent()" condenseWhite="true" restrict=". 0-9"/>
		<mx:Label text="X" fontWeight="bold" width="15"/>
		<mx:TextInput id="xScroll" width="45"/>
		<mx:Label text="Y" fontWeight="bold" width="15"/>
		<mx:TextInput id="yScroll" width="45"/>
		<mx:Button label="ScrollTo" click="scrollTo(Number(xScroll.text), Number(yScroll.text))" width="70"/>
		<mx:Label text="DragDelay(ms)" fontWeight="bold" width="93"/>
		<mx:TextInput id="DragDelay" width="45" change="updateScrollDragDelay()" condenseWhite="true" restrict="0-9"/>
		<mx:Label text="DragPixels" fontWeight="bold" width="67"/>
		<mx:TextInput id="DragPixels" width="45" change="updateScrollDragPixels()" condenseWhite="true" restrict="0-9"/>
		<mx:Label text="Wheel" fontWeight="bold" width="45"/>
		<mx:TextInput id="MouseWheelMultiplier" width="45" change="updateScrollMouseWheelMultiplier()" restrict="0-9" condenseWhite="true"/>
		<mx:Label text="maxX" fontWeight="bold" width="40"/>
		<mx:Label id="maxX" fontWeight="normal" width="40"/>
		<mx:Label text="maxY" fontWeight="bold" width="60"/>
		<mx:Label id="maxY" fontWeight="normal" width="60" fontStyle="normal"/>
	</mx:HBox>
</mx:HBox>
