<?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:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%" height="100%" initialize="init()" resize="handleResize()" horizontalScrollPolicy="off" verticalScrollPolicy="off" xmlns:local="*" backgroundColor="#FFFFFF">
	<!-- This file loads and parses a TextFlow markup file and attaches it to the SimpleEditorPanel  -->
	<mx:Script>
		<![CDATA[
			import flashx.textLayout.elements.TextFlow;
			import flashx.textLayout.conversion.TextConverter;
			
			import flash.events.Event;
			import flash.events.IOErrorEvent;
			
			import mx.controls.Alert;
			import mx.events.StyleEvent;
			
			static private const simpleText:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'>"
   				+ "<p styleName='center'><span>There are many </span><span styleName='italic'>such</span><span> lime-kilns in that tract of country, for the purpose of burning the white marble which composes a large part of the substance of the hills. Some of them, built years ago, and long deserted, with weeds growing in the vacant round of the interior, which is open to the sky, and grass and wild-flowers rooting themselves into the chinks of the stones, look already like relics of antiquity, and may yet be overspread with the lichens of centuries to come. Others, where the lime-burner still feeds his daily and nightlong fire, afford points of interest to the wanderer among the hills, who seats himself on a log of wood or a fragment of marble, to hold a chat with the solitary man. It is a lonesome, and, when the character is inclined to thought, may be an intensely thoughtful occupation; as it proved in the case of Ethan Brand, who had mused to such strange purpose, in days gone by, while the fire in this very kiln was burning.</span></p>"
				+ "<p><span>The man who now watched the </span><span id='bold'>fire</span><span> was of a </span><span typeName='foo'>different</span><span> order, and troubled himself with no thoughts save the very few that were requisite to his business. At frequent intervals, he flung back the clashing weight of the iron door, and, turning his face from the insufferable glare, thrust in huge logs of oak, or stirred the immense brands with a long pole. Within the furnace were seen the curling and riotous flames, and the burning marble, almost molten with the intensity of heat; while without, the reflection of the fire quivered on the dark intricacy of the surrounding forest, and showed in the foreground a bright and ruddy little picture of the hut, the spring beside its door, the athletic and coal-begrimed figure of the lime-burner, and the half-frightened child, shrinking into the protection of his father's shadow. And when again the iron door was closed, then reappeared the tender light of the half-full moon, which vainly strove to trace out the indistinct shapes of the neighboring mountains; and, in the upper sky, there was a flitting congregation of clouds, still faintly tinged with the rosy sunset, though thus far down into the valley the sunshine had vanished long and long ago.</span></p>"
 				+ "</TextFlow>";
			
			/** Initialize the application */
			private function init():void
			{
				// adjust the selection color when focus is not on the selection to look the same.  
				// This is appropriate for an editor but not for UI widgets
				TextFlow.defaultConfiguration.unfocusedSelectionFormat = TextFlow.defaultConfiguration.focusedSelectionFormat;
				
		
				var textFlow:TextFlow = TextConverter.importToFlow(simpleText, TextConverter.TEXT_LAYOUT_FORMAT);
				// wipe out the default inherits - format take precendence over CSS - this simplifies the example
				textFlow.format = null;
				// attach a format resolver
				textFlow.formatResolver = new CSSFormatResolver(styleManager);
				// set it into the editor
				editor.textFlow = textFlow;
				
				loadStyle("SimpleCSS.swf");
				
				handleResize();
			}
			
			/** on file load error show the error string */
			private function errorHandler(e:IOErrorEvent):void
			{
				editor.textFlow = TextConverter.importToFlow("\n"+IOErrorEvent(e).text, TextConverter.PLAIN_TEXT_FORMAT);
			}
			/** on success parse the file and display it */
			private function loadCompleteHandler(e:Event):void
			{
		 		editor.textFlow = TextConverter.importToFlow(e.target.data, TextConverter.TEXT_LAYOUT_FORMAT);
		 		editor.textFlow.formatResolver = new CSSFormatResolver(styleManager);
			}
			
			/** Update the size of the editor to be the full size of this window */
			private function handleResize():void
			{
				if (editor)
					editor.setSize(this.width,this.height);
			}
			
			 		// styles loaded - invalidate the defaultFlow and force recompose
	 		private function styleEventComplete(e:StyleEvent):void
	 		{
	 			if (editor.textFlow)
	 			{
					editor.textFlow.invalidateAllFormats();
					editor.textFlow.flowComposer.updateAllControllers();
	 			}
	 		}
	 		
	 		private function styleEventError(e:StyleEvent):void
	 		{
	 			Alert.show("Unable to load stylesheet: " + e.errorText);
	 		}
	 		
	 		public function loadStyle(styleSheetToLoad:String):void
	 		{
	 			// Next three lines load flowCss and set it as the style
				var dispatcher:IEventDispatcher = styleManager.loadStyleDeclarations(styleSheetToLoad);
				dispatcher.addEventListener(StyleEvent.COMPLETE,styleEventComplete,false,0,true);
				dispatcher.addEventListener(StyleEvent.ERROR,styleEventError,false,0,true);
	 		}
		]]>
	</mx:Script>
	<local:SimpleEditorPanel id="editor"/>

</mx:Application>
