import mx.utils.Delegate;
class CircleMap {
	/*----------------------------------------------------------------
	variable declarations and initializations
	----------------------------------------------------------------*/
	private static var timeline_mc:MovieClip = _root;
	private static var circle_xml:XML = new XML();
	private static var unitMaxNum:Number = 0;
	private static var hierMax:Number = 0;
	private static var pages_array:Array = new Array();
	private static var rotations_array:Array = new Array();
	private static var drawing_mc:MovieClip = timeline_mc.createEmptyMovieClip("drawing_mc", 1);
	private static var process_array:Array = new Array();
	private static var unitPitch:Number = 1;
	private static var maru_mc:MovieClip = timeline_mc.maru_mc;
	private static var info_mc:MovieClip = timeline_mc.info_mc;
	private static var pageInfo_mc:MovieClip = timeline_mc.pageInfo_mc;
	/*----------------------------------------------------------------
	functions
	----------------------------------------------------------------*/
	private function CircleMap() {
	}
	/*----------------------------------------------------------------
	run immediately
	----------------------------------------------------------------*/
	static function buildCircleMap(xmlFile_str:String) {
		circle_xml.ignoreWhite = true;
		circle_xml.onLoad = Delegate.create(circle_xml, onXmlLoad);
		circle_xml.load(xmlFile_str);
	}
	static function resetAll():Void {
		Circle.reset();
		info_mc.clearText();
		PageInfo.reset();
		Page.reset();
		initProperties();
	}
	static function initProperties():Void {
		circle_xml = new XML();
		unitMaxNum = 0;
		hierMax = 0;
		pages_array = new Array();
		rotations_array = new Array();
		process_array = new Array();
		unitPitch = 1;
		drawing_mc.swapDepths(1);
	}
	static function showChildren(startNode:XMLNode, level:Number, parentID_str:String):Void {
		if (parentID_str == undefined) {
			parentID_str = "0";
		}
		//if ((startNode.hasChildNodes())&&(startNode.attributes.utype == "111")) {             
		if (startNode.hasChildNodes()) {
			if (pages_array.length<++level) {
				pages_array[level-1] = new Array();
			}
			if ((level>hierMax) && (startNode.attributes.utype == "111")) {
				hierMax = level;
			}
			var childNodes_array:Array = startNode.childNodes;
			var nLength:Number = childNodes_array.length;
			for (var i:Number = 0; i<nLength; i++) {
				var childNode:XMLNode = childNodes_array[i];
				if ((childNode.nodeType == 1) && (childNode.attributes.utype == "111")) {
					unitMaxNum++;
					var data:Object = childNode.attributes;
					data.parent = parentID_str;
					data.level = level;
					pages_array[level-1].push(data);
				} else {
				}
				// *recursion cannot exceed 256 times
				arguments.callee(childNode, level, data.id);
			}
		}
	}
	static function drawCircleMap(level:Number, nPitch:Number):Void {
		var r_max:Number = Math.min(Stage.width, Stage.height)-10;
		var x_center:Number = Stage.width-10-(r_max/2);
		var y_center:Number = Stage.height/2;
		trace("x_center : "+x_center);
		trace("y_center : "+y_center);
		trace("r_max : "+r_max);
		trace("level : "+level);
		sortPages();
		var nNextDepth:Number = Circle.drawCircle(level, x_center, y_center, r_max, 100);
		drawing_mc.swapDepths(nNextDepth++);
		PageInfo.setDepth(nNextDepth++);
		delayProcess(null, createPages, [level, x_center, y_center, r_max, nNextDepth, nPitch]);
		var nRadius:Number = (r_max/level/2);
		delayProcess(null, alignPages);
	}
	static function delayProcess(target:Object, process:Function, args_array:Array):Void {
		process_array.push({target:target, func:process, args:args_array});
		if (!timeline_mc.onEnterFrame) {
			timeline_mc.onEnterFrame = executeProcess;
		}
	}
	static function executeProcess():Void {
		if (process_array.length) {
			var oProcess:Object = process_array.shift();
			oProcess.func.apply(oProcess.target, oProcess.args);
		} else {
			delete timeline_mc.onEnterFrame;
			// complete();
		}
	}
	// function complete() {}
	static function createPages(level:Number, x_center:Number, y_center:Number, r_max:Number, nDepth:Number, nPitch:Number):Void {
		// trace([unitPitch, nPitch]);
		var source_mc:MovieClip = Page.getOriginal();
		source_mc.setScale(r_max/level);
		var nRadius:Number = (r_max/level/2);
		Page.setBaseData(x_center, y_center, nRadius, drawing_mc);
		var nLength:Number = pages_array.length;
		for (var i:Number = 0; i<nLength; i++) {
			var _array:Array = pages_array[i];
			var nLength2:Number = _array.length;
			rotations_array[i] = 0;
			for (var j:Number = 0; j<nLength2; j++) {
				var id_str:String = String(1000000+(i+1)*1000+j+1).substr(1);
				var oData:Object = _array[j];
				var _mc:MovieClip = Page.createPage("p-clone"+id_str, nDepth++, oData);
				_mc.addToParent();
				_mc.setPosition(-unitPitch*1000*j, true);
			}
		}
		Page.setPagesData(pages_array);
	}
	static function sortPages():Void {
		var nLength:Number = pages_array.length;
		var child_array:Array = new Array();
		for (var i:Number = 0; i<nLength-1; i++) {
			var source_array:Array = pages_array[i];
			var next_array:Array = pages_array[i+1];
			var _array:Array = new Array();
			var nLength2:Number = source_array.length;
			if (i>=1 && nLength*nLength2>0) {
				var unit:Number = i/nLength/nLength2;
				if (unitPitch>unit) {
					unitPitch = unit;
				}
			}
			for (var j:Number = 0; j<nLength2; j++) {
				var oElement:Object = source_array[j];
				_array.push(oElement);
				var id_str:String = oElement.id;
				for (var k:Number = next_array.length; k>=0; k--) {
					if (id_str == next_array[k].parent) {
						child_array.push(next_array.splice(k, 1)[0]);
					}
				}
			}
			pages_array[i] = _array;
			pages_array[i+1] = child_array.concat(next_array);
			child_array = new Array();
		}
	}
	static function alignPages():Void {
		var nLength:Number = pages_array.length;
		for (var i:Number = 1; i<nLength; i++) {
			var _array:Array = pages_array[i];
			delayProcess(null, _alignPages, [_array]);
		}
	}
	static function _alignPages(_array:Array):Void {
		var nLength:Number = _array.length;
		for (var i:Number = 0; i<nLength; i++) {
			var _mc:MovieClip = _array[i].mc;
			delayProcess(_mc, _mc.centerAmongChildren);
		}
	}
	/*----------------------------------------------------------------
	event handlers
	----------------------------------------------------------------*/
	static function onXmlLoad(p_success:Boolean):Void {
		if (p_success) {
			trace(": : Circle XML LOADED : :");
			showChildren(circle_xml.firstChild.firstChild, 0);
			drawCircleMap(hierMax, 100*(hierMax+1)/unitMaxNum);
			var infoObject:Object = circle_xml.firstChild.attributes;
			var type_str:String = infoObject["type"];
			var target_str:String = infoObject["target"];
			info_mc.displayInfo(type_str, target_str, unitMaxNum, hierMax);
			/*
			-- wanted to put pageInfo_mc on the top. --
			var max_depth:Number = _parent.pageInfo_mc.getNextHighestDepth();
			trace( "max_depth = "+max_depth);
			_parent.pageInfo_mc.swapDepths(_parent.pageInfo_mc.getNextHighestDepth());
			*/
		} else {
			trace(": : Circle XML ERROR : :");
		}
	}
}
