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

-->
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
					   xmlns:s="library://ns.adobe.com/flex/spark" 
					   xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="windowedapplication1_creationCompleteHandler(event)">
	<fx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.events.FlexEvent;
			
			private var sourceFile:File = new File();			
			private var sourcePath:String;
			private var sourceDir:String;
			private var slash:String;
			private var sourceStream:FileStream;
			private var sourceString:String;
			private var sourceXML:XML;
			private var fxgNS:Namespace = new Namespace(null,"http://ns.adobe.com/fxg/2008");
			private var flmNS:Namespace = new Namespace("flm","http://ns.adobe.com/flame/2008");
			private var aiNS:Namespace = new Namespace("ai","http://ns.adobe.com/ai/2009");
			private var ateNS:Namespace = new Namespace("ate","http://ns.adobe.com/ate/2009");
			private var dNS:Namespace = new Namespace("d","http://ns.adobe.com/fxg/2008/dt");

			protected function windowedapplication1_creationCompleteHandler(event:FlexEvent):void
			{
				XML.ignoreComments = false;
				XML.prettyPrinting = true;
			}
			
			private function browse():void
			{
				var fxgFilter:FileFilter = new FileFilter("FXG", "*.fxg");
				sourceFile.browseForOpen("Select FXG file", [fxgFilter]);
				sourceFile.addEventListener(Event.SELECT, fileSelected);
			}
			
			private function fileSelected(event:Event):void
			{
				sourceFileTI.text = sourceFile.nativePath;
			}
			
			
			
			private function readFile():void
			{
				if (Capabilities.os.indexOf("Windows") != -1)
					slash = "\\";
				else
					slash = "/";
				
				sourceFile.nativePath = sourceFileTI.text;	
				sourcePath = sourceFile.nativePath;
				var c:int = sourcePath.lastIndexOf(slash);
				sourceDir = sourcePath.substring(0, c);
				
				sourceStream = new FileStream();
				sourceStream.open(sourceFile, FileMode.READ);
				sourceString = sourceStream.readUTFBytes(sourceStream.bytesAvailable);
				
				sourceXML = XML(sourceString);
			}
			
			private function writeFXG():void
			{
				readFile();
				callLater(makeFXGFiles);
			}
			
			private var topTags:XMLList;
			private var numTags:int;
			private var curTag:int = 0;
			
			private var symbols:Object = {};
			private var symbolList:Array = [];
			
			private function makeFXGFiles():void
			{
				default xml namespace = fxgNS;
				
				var syms:XMLList = sourceXML.Library.children();
				var n:int = syms.length();
				for (var i:int = 0; i < n; i++)
				{
					var node:XML = syms[i];
					symbols[node.@name] = node;
				}
				callLater(makeFXGFile);
			}	
			
			private function makeFXGFile():void
			{
				for each (var symbolXML:XML in symbols)
				{
					var newFXG:XML = getNewFXG(symbolXML);
					
					// write out file
					var destFile:File = new File(sourceDir + slash + "fxg" + slash + symbolXML.@name + ".fxg");
					var writeStream:FileStream = new FileStream();
					writeStream.open(destFile, FileMode.WRITE);
					writeStream.writeUTFBytes(newFXG.toXMLString());
					writeStream.close();
				}
				Alert.show("FXG creation complete!","Process complete");
			}
			
			private function getNewFXG(v:XML):XML
			{
				var childFXG:XML = optimizeFXG(v.copy());
				var newFXG:XML = v.copy();
				var newName:String = newFXG.@name
				// change name from 'Definition' to 'Graphic'
				newFXG.setName("Graphic");
				
				// delete name attribute
				delete newFXG.@name;
				
				// add version
				newFXG.@version = "2.0";
				newFXG.setChildren(childFXG);
				newFXG = removeCruft(newFXG);
				return newFXG;
			}
			
			private function optimizeFXG(v:XML):XML
			{
				var children:XMLList = v.children();
				var outputXML:XML;
				if(children.length() == 1)
				{
					outputXML = simplify(children[0]);
				}
				else
				{
					for each (var child:XML in children)
					{
						if(child.localName() != "Private")
						{
							outputXML.appendChild(simplify(child));	
						}
					}
				}
				return outputXML;
			}
			
			private function simplify(v:XML):XML
			{
				if(v.localName() == "Group")
				{
					if(v.children().length() == 1)
					{
						return simplify(v.children()[0]);
					}
					else
					{
						return v;
					}
				}
				else
				{
					return v;
				}
			}
			
			private function removeCruft(v:XML):XML
			{
				//Remove unused attributes
				var attributes:XMLList = v.attributes();
				for(var i:int=attributes.length()-1; i>=0; i--)
				{
					var attribute:XML = attributes[i];
					var ns:Namespace = attribute.namespace();
					if(ns.uri == aiNS.uri || ns.uri == flmNS.uri || ns.uri == ateNS.uri || ns.uri == dNS.uri)
					{
						use namespace ns;
						delete attributes[i];
					}
				}
				//Process children
				for each (var child:XML in v.children())
				{
					removeCruft(child);					
				}

				return v;
			}
			
		]]>
	</fx:Script>
	<s:VGroup width="100%" >
		<s:HGroup width="100%">
			<s:Label text="Source File:" />
			<s:TextInput id="sourceFileTI" width="100%" />
			<s:Button label="Browse..." click="browse()" />
		</s:HGroup>
		<s:HGroup width="100%">
			<s:Button label="Create and optimize FXG symbols" click="writeFXG()" />
			<!--<s:Button label="Optimize FXG" click="optimizeFXG()" />-->
		</s:HGroup>
		<s:Label id="errorLabel" />		
	</s:VGroup>
</s:WindowedApplication>
