//リストオブジェクト
function List(){ 
	this.head    = null; 
	this.end     = null; 
	this.current = null;
	this.size    = 0;
} 

//リストにノードを追加する
List.prototype.add = function( inObj ){ 
	var node = { obj:inObj ,next:null }; 
	if( this.head ){ 
		this.end.next = node; 
		this.end	  = node; 
	}
	else{ 
		this.head    = node; 
		this.end     = node; 
		this.current = node; 
	} 
	this.size++;
} 

//リストから次のノードを取得する
List.prototype.next = function(){ 
	var node = null;
	if( this.current ){ 
		node		 = this.current.obj; 
		this.current = this.current.next;
	}
	return node; 
} 

//リストから次のノードが存在するかを確認する
List.prototype.hasnext = function(){ 
	if( this.current != null ) return true; 
	return false; 
}
// リストの先頭に戻す
List.prototype.goHead = function(){ 
	this.current = this.head;
}
//リストから次のノードが存在するかを確認する
List.prototype.getNode = function( inName ){ 
	if( this.head != null ){
		this.goHead();
		while ( this.hasnext()) {
			nodeSwap = this.next();
			if( nodeSwap.name == inName ){
				return nodeSwap;
			}
		}
	}; 
	return null;
}
// ﾃﾞｰﾀ要素
function Node( inName, inColor ,inLabel ,inPosX, inPosY, inTool ){ 
	//ﾃﾞｰﾀ要素の属性設定
	this.name			= inName ;
	this.lbl			= inLabel;									// ﾉｰﾄﾞ名称(表示用)
	this.color			= inColor;									// ﾉｰﾄﾞの色
	this.posX			= inPosX;									// X座標
	this.posY			= inPosY;									// Y座標
	this.preNode		= null;										// 前ﾉｰﾄﾞの名称
	this.pstNode		= null;										// 後ﾉｰﾄﾞの名称
	this.stateObj		= null;										// 描画用ｽﾃｰﾄｵﾌﾞｼﾞｪｸﾄ
	this.color1			= null;										// 前ﾉｰﾄﾞの色
	this.color2			= null;										// 前ﾉｰﾄﾞの色
	this.tooltip		= inTool;
}
// メイン処理（描画）
function draw(){
	var SYS_TOP_X  		= -50;										// X座標原点
	var SYS_TOP_Y  		= -50;										// Y座標原点
	var SYS_STEP_X 		= 80;										// X方向の歩幅
	var SYS_STEP_Y 		= 80;										// Y方向の歩幅
	var SYS_RADIUS 		= 20;										// ﾉｰﾄﾞの描画半径
	var SYS_MARGIN 		= 50;										// ﾉｰﾄﾞの描画半径
	// 要素の最大配置座標を記録する変数
	var maxPosX    = SYS_TOP_X + SYS_STEP_X;						// X座標最大値
	var maxPosY    = SYS_TOP_Y + SYS_STEP_Y;						// Y座標最大値
	try{
		// 画面のHTMLより元ネタのiStruct取得
//		var keyBreak   = $("iStruct").get(0).keyBreak;				// 一番目のｽﾄﾗｸﾁｬｰのみ描画させる
		var keyBreak   = $("iStruct").attr("keyBreak")
		var structObjs = $("iStruct[keyBreak='" + keyBreak+ "']");	// 一番目のｽﾄﾗｸﾁｬｰ要素を取得する
		var connCount  = structObjs.length;

		// 元ネタのHTMLを隠す
		$("#viewTable").hide();
	}catch(e){
		// HTML要素が取得できなければ終了
		return;
	}
	// 全ﾃﾞｰﾀﾉｰﾄﾞの座標計算
	var nodeList = new List(); 										// ﾃﾞｰﾀﾉｰﾄﾞﾘｽﾄ
	var posX 	 = SYS_TOP_X;										// X出発点
	var posY 	 = SYS_TOP_Y;										// Y出発点
	// 
	for( var i= 0 ;i < connCount ;i++ ){
		// 前ﾉｰﾄﾞ
		if( !nodeList.getNode( $(structObjs[i]).attr("preNode") )){
			pstNodeObj = nodeList.getNode( $(structObjs[i]).attr("pstNode") );
			if( pstNodeObj ){
				lastPreNodeObj = nodeList.getNode( pstNodeObj.preNode );
				posX = lastPreNodeObj.posX;
				posY = lastPreNodeObj.posY + 100;
			}
			else{
				posX = posX + SYS_STEP_X;
				posY = posY + SYS_STEP_Y;
			}
			var dataObj = new Node(  //structObjs[i].preNode			// code
									//,structObjs[i].color1			// color
									//,structObjs[i].prelbl			// lbl
									$(structObjs[i]).attr("preNode")
									,$(structObjs[i]).attr("color1")
									,$(structObjs[i]).attr("prelbl")
									,posX							// posX
									,posY							// posY
									,null
							);
			nodeList.add( dataObj );
		}
		// 後ﾉｰﾄﾞ
		if( !nodeList.getNode( $(structObjs[i]).attr("pstNode") )){
			preNodeObj = nodeList.getNode( $(structObjs[i]).attr("preNode") );
			if( preNodeObj ){
				lastPstNodeObj = nodeList.getNode( preNodeObj.pstNode );
				if( lastPstNodeObj ){
					posX = lastPstNodeObj.posX;
					posY = lastPstNodeObj.posY + 50;
				}
				else{
					posX = preNodeObj.posX + 200;
					posY = preNodeObj.posY;
				}
			}
			var dataObj = new Node(  $(structObjs[i]).attr("pstNode")			// code
									,$(structObjs[i]).attr("color2")			// color
									,$(structObjs[i]).attr("pstlbl")			// lbl
									,posX							// posX
									,posY							// posY
									,$(structObjs[i]).attr("tooltip")
							);
			nodeList.add( dataObj );
		}
		nodeList.getNode( $(structObjs[i]).attr("preNode") ).pstNode = $(structObjs[i]).attr("pstNode");
		nodeList.getNode( $(structObjs[i]).attr("pstNode") ).preNode = $(structObjs[i]).attr("preNode");
		// ﾉｰﾄﾞの配置範囲
		maxPosX = posX > maxPosX ? posX : maxPosX;
		maxPosY = posY > maxPosY ? posY : maxPosY;
	}
	// カンバスのサイズ計算
	maxPosX   = maxPosX + SYS_RADIUS + SYS_MARGIN;
	maxPosY   = maxPosY + SYS_RADIUS + SYS_MARGIN;
	// 描画準備
	var paper = Joint.paper("graphDiv" ,maxPosX+100 ,maxPosY );
	var fsa   = Joint.dia.fsa;
	// ﾉｰﾄﾞの描画
	nodeList.goHead();										// ポインタをヘッドに移動

	while( nodeList.hasnext() ){
		var swapNode	= nodeList.next();
		var posXnode	= swapNode.posX;
		var name		= swapNode.lbl;
		var color		= swapNode.color;
		var radius		= SYS_RADIUS;
		var offsetX		= SYS_RADIUS -15;
		var offsetY		= SYS_RADIUS -10;
		var tooltip		= swapNode.tooltip;
		if ( swapNode.name == 'START'){
			color		= 'white';
		}
		if ( swapNode.name == 'END'){
			posXnode	= maxPosX;
		}
		if ( swapNode.name.substr(0,1) == 'X'){
			name		= '';
			radius		= 10;
			offsetX		= 5;
			offsetY		= 5;
		}
		if ( tooltip == null ){
			tooltip = "";
		}


		var newStateObj = fsa.State.create({ attrs        : { fill: color, title:tooltip }
											,radius       : radius
											,position     : { x:posXnode, y:swapNode.posY }
											,label        : name
											,labelOffsetX : offsetX
											,labelOffsetY : offsetY
										});
		swapNode.stateObj = newStateObj ;
	}
	// ﾉｰﾄﾞ間の矢印を描画
	for( var i= 0 ;i < connCount ;i++ ){
		var preNodeObj = nodeList.getNode( $(structObjs[i]).attr("preNode") );
		var pstNodeObj = nodeList.getNode( $(structObjs[i]).attr("pstNode") );
		preNodeObj.stateObj.joint( pstNodeObj.stateObj 
								  ,{ label: $(structObjs[i]).attr("relation") ,interactive:false }
							  );
	}
}
