/* version: 0.0.1 
 * author : Sen Li
 * date   : 2012/05/10
 * 機能   : ガント図の描画
 *          2012/10/01 Takahashi Masakazu stackGantt機能追加
 */

/*
 * 変数を隠蔽するため、クロージャー化します。
 */
var adjustGantTable = (function(){

// 属性変数
var gantZoom;							// ガントズーム
var gantStartDate;						// ガントの描画開始日付(時間)
var gantEndDate;						// 
var daySpan;
var skipHoliday;						// 休日を飛ばすか
var arrCalender;						// カレンダー配列
var verticalShift = "true";				// ガントバー要素の縦方向でずらす
var margeRows	  = "false";			// 複数行のマージ、条件：前の行のデータと一致する時
var fixedCols	  = 0;					// 列固定、固定列の数
var useBgColor	  = "true";				// 縞々背景色の使用 2012/09/26 ADD
// StackGantt用 2012/10/01
// var stdUpper	  = 1.0;	// 2012/09/26 DEL
// var stdCost	  = 1.0;	// 2012/09/26 DEL
// var stdLower	  = 0;		// 2012/09/26 DEL
var viewGantt	  = "true";				// stack時のガント積上げ
var viewMode	  = "1";				// stack時のガント積上げ
var stackHoliday  = "true";				// 休日も積上げするかどうか

// 全域変数
var hoursPreDay;						// 一日の描画時間数
var gantStartTime;						// 始業時間
var gantEndTime;						// 終業時間
// ガントバー移動用の変数
var hilightBar = null;
var startX;
var oriLeft;
var oriWidth;
var cnBunkatu  = 3;
var startDateInputObj = null;
var endDateInputObj = null;
var startTimeInputObj = null;
var endTimeInputObj = null;
var calenderDays=0;
// Mouse Action
var cnMNone    = 0;
var cnMLeft    = 1;
var cnMMiddle  = 2;
var cnMRight   = 3;
var nLeftRightLimit = 2;		// sayu no tukamishiro no saishou-chi
var nMAction;

// システム定数
var SYS_BAR_HEIGHT		 	= 10;		// ガントバー要素の高さ
var SYS_MIN_HEIGHT_SHIFT 	= 40;		// ガントバー要素の縦方向でずらす場合の行高さ
var SYS_MIN_HEIGHT_NO_SHIFT = 30;		// ガントバー要素の縦方向でずらさない場合の行高さ
var SYS_MARKER_OFFSET_H	 	= 3;		// マーカーとバーの縦方向の相対位置
var SYS_CELLPADDING			= 0;		// 
var SYS_NUMBER_CELLS		= 3;		// viewTableの番号列の数
var SYS_OFFSET_LEFT			= -1;		// 
// stackGantt用 2012/10/01
var SYS_STD_COST			= 'stdcost';  //標準工数内の場合に付くクラス名
var SYS_UPPER_COST			= 'uppercost';//工数が超えた場合に付くクラス名
var SYS_LOWER_COST			= 'lowercost';//工数が不足した場合に付くクラス名
var SYS_WARN_COST			= 'warncost';
var SYS_ERROR_COST			= 'errorcost';
var SYS_WARN_BOUND		 	= 1.5;		  //標準能力 ～ 標準能力*1.5 の間は警告域とする。
var SYS_STDCOST				= 1;		  //2012/09/26 ADD	
var SYS_LINK_TARGET			= "CONTENTS"; //デフォルトリンク先 2012/09/27 ADD

/*
    ZOOM  ラベル        日数ピクセル変換率          ヘッダ上      ヘッダ下    1文字(CSS)
  ==================================================================================
     0 : １週間 日数 * 12 * 4     48   48px =  1日  [02/   ]      [23(EE)]       8px
     1 : ２週間 日数 * 12 * 2     24   24px =  1日  [02/]         [23 ]          8px
     2 : １ヶ月 日数 * 12         12   12px =  1日  [2]           [3]           12px
     3 : ２ヶ月 日数 * 12 / 1.5    8   56px =  7日  [2004/  ]     [02/03  ]      8px
     4 : ３ヶ月 日数 * 12 / 3      4   56px = 14日  [2004/  ]     [02/03  ]      8px
     5 : ４ヶ月 日数 * 12 / 4      3   90px = 30日  [2004/     ]  [02/03     ]   9px
     6 : ６ヶ月 日数 * 12 / 6      2   60px = 30日  [2004/ ]      [02/03 ]      10px
     7 : １年   日数 * 12 / 12     1   90px = 90日  [2004/     ]  [02/03     ]   9px
     8 : ２年   日数 * 12 / 24    0.5  90px =180日  [2004/     ]  [02/03     ]   9px
     9 : ３年   日数 * 12 / 36    0.33 60px =180日  [2004/ ]      [02/03 ]      10px
    10 : 週単位 日数 * 12 / 3.5   3.43 24px =  7日  [19W]         [12 ]          8px
    20 : 1時間  時間 * 12 * 4       48 48px = 1時間 [02日]        [07h ]        12px
    21 : 1時間2 時間 * 12 * 2       24 24px = 1時間 [02]          [07]          12px
    22 : 2時間  時間 * 12 * 4 /  2  24 48px = 2時間 [02日]        [07h ]        12px
    23 : 2時間2 時間 * 12 * 2 /  2  12 24px = 2時間 [02]          [07]          12px
    24 : 4時間  時間 * 12 * 4 /  4  12 48px = 4時間 [02日]        [07h ]        12px
    25 : 4時間2 時間 * 12 * 2 /  4   6 24px = 4時間 [02]          [07]          12px
    26 : 6時間  時間 * 12 * 4 /  6   8 48px = 6時間 [02日]        [07h ]        12px
    27 : 6時間2 時間 * 12 * 2 /  6   4 24px = 6時間 [02]          [07]          12px
    28 : 8時間  時間 * 12 * 4 /  8   6 48px = 8時間 [02日]        [07h ]        12px
    29 : 8時間2 時間 * 12 * 2 /  8   3 24px = 8時間 [02]          [07]          12px
    30 :12時間  時間 * 12 * 4 / 12   4 48px =12時間 [02日]        [07h ]        12px
    31 :12時間2 時間 * 12 * 2 / 12   2 24px =12時間 [02]          [07]          12px 
    DAY   : １週間 日数 * 12 * 4     48   48px =  1日  [02/   ]      [23(EE)]       8px
    MONTH : １年   日数 * 12 / 12     1   90px = 30日  [2004/     ]  [02/03     ]   9px
    WEEK  : 週単位 日数 * 12 / 3.5   3.43 42px =  7日  [19W   ]      [12    ]       8px
*/
// ガントセル幅
var unitPixel = {"0" : 48 ,"1" : 24 ,"2" : 12 ,"3" : 56 ,"4" : 56 ,"5" : 90 ,"6" : 60 ,"7" : 90 ,"8" : 90 ,"9" : 60 ,"10": 24 ,"20": 48 ,"21": 24 ,"22": 48 ,"23": 24 ,"24": 48 ,"25": 24 ,"26": 48 ,"27": 24 ,"28": 48 ,"29": 24 ,"30": 48 ,"31": 24
					,"DAY" : 48 ,"MONTH" : 90 ,"WEEK": 48};
// ガントセル毎の日数・時間数
var unitSpan  = {"0" : 1  ,"1" : 1  ,"2" : 1  ,"3" : 7  ,"4" : 14 ,"5" : 30 ,"6" : 30 ,"7" : 90 ,"8" :180 ,"9" :180 ,"10":  7 ,"20":  1 ,"21":  1 ,"22":  2 ,"23":  2 ,"24":  4 ,"25":  4 ,"26":  6 ,"27":  6 ,"28":  8 ,"29":  8 ,"30": 12 ,"31": 12 
					,"DAY" : 1  ,"MONTH" : 30 ,"WEEK":  7};

//リストオブジェクト
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; 
}

// Arrayコピー用のメソッドを追加する。
Array.prototype.clone = function(){
    return Array.apply(null,this)
}
// Arrayに要素の存在チェックするためのメソッドを追加する。
Array.prototype.contains = function( value ){
	for(var i = 0; i < this.length; i++){
		if(this[i] === value){
			return true;
		}
	}
	return false;
};
// ２つの日付の差分を計算する
function compareDate( inDate1, inDate2) {
	if( inDate1 == null || inDate2 == null ){return 0;}
	if( inDate1.length != 8 || inDate2.length != 8 ){return 0;}
	var year1  = inDate1.substring( 0 ,4 );
	var month1 = inDate1.substring( 4 ,6 );
	var day1   = inDate1.substring( 6 ,8 );
	var year2  = inDate2.substring( 0 ,4 );
	var month2 = inDate2.substring( 4 ,6 );
	var day2   = inDate2.substring( 6 ,8 );
    var dt1 = new Date(year1, month1 - 1, day1);
    var dt2 = new Date(year2, month2 - 1, day2);
    var diff = dt1 - dt2;
    var diffDay = diff / 86400000;		// 1日の86400000ミリ秒数
    return diffDay;
}
//x.x時間⇒時分HH24MM
function toTime( inHour ) {
	var hour  = ( "00" + Math.floor( inHour ).toString()).slice(-2); 
	var minus = ("00" + Math.floor(( inHour - Math.floor( inHour )) * 60 ).toString()).slice(-2);
	return  hour + minus;
}
//時分HH24MM⇒x.x時間へ変換
function toHour( inTime ) {
	var hour  = inTime.substring( 0 ,2);
	var minus = inTime.substring( 2 ,4);
	var rtnHour = parseInt( hour ,10 ) + parseInt( minus ,10 ) / 60;
	return Math.round( rtnHour*100 )/100;
}
// 月を足します rtnDayは日(0だと月末) 2012/10/01
function addMonth( inDate, addMnt, rtnDay ) {
	var year  = inDate.substring( 0 ,4 );
	var month = inDate.substring( 4 ,6 );
	var day   = inDate.substring( 6 );
	var adjustMonth = 1;
	if (rtnDay == 0 ){
		var adjustMonth = 0;
	}

	month = (Number(month) + Number(addMnt) - Number(adjustMonth)) % 12;
	var addY = Math.floor((Number(month) + Number(addMnt) - Number(adjustMonth)) / 12);
	year = Number(year) + Number(addY);

	var rtnDate = new Date( year, month, rtnDay );
	return rtnDate.getFullYear() + ( "00" + ( rtnDate.getMonth() + 1 ) ).slice( -2 ) + ("00" + rtnDate.getDate()).slice( -2 );
}
//n日後、n日前の日付を求める
function addDays( inDate ,inDays ,inFGCal ) {
	var year  = inDate.substring( 0 ,4 );
	var month = inDate.substring( 4 ,6 );
	var day   = inDate.substring( 6 ,8 );
	var rtnDate = new Date( year, month - 1, day );
	var baseSec = rtnDate.getTime();

	//カレンダー参照
	var startDate = inDate.substring( 0 ,8 );
	var diffDayS   = compareDate( startDate ,gantStartDate );

	var workDays = 0;
	var countDays = 0;
	// カレンダー参照かつ休日を飛ばす場合かつ時間単位のガントの場合
	if( inFGCal == "1" && skipHoliday == "true" && parseInt( gantZoom ,10 ) >= 20){
		// 前方へ移動
		if( inDays > 0 ){
			//カレンダーの日数
			for( var i = diffDayS ; workDays <= inDays && i <=calenderDays ;i++ ){
				if( arrCalender[i] == "0" ){ workDays++;}
				countDays++;
			}
			countDays--;
		}
		// 後方へ移動
		else if( inDays < 0 ){
			//カレンダーの日数
			for( var i = diffDayS ; workDays >= inDays && i >=0 ;i-- ){
				if( arrCalender[i] == "0" ){ workDays--;}
				countDays--;
			}
			countDays++;
		}
	}
	//カレンダー参照しないOR休日出力されている
	else{
		countDays = inDays;
	}
	var addSec  = countDays * 86400000;	// 1日の86400000ミリ秒数
	var targetSec = baseSec + addSec;
	rtnDate.setTime( targetSec );
	return rtnDate.getFullYear() + ( "00" + ( rtnDate.getMonth() + 1 ) ).slice( -2 ) + ("00" + rtnDate.getDate()).slice( -2 );
}

//n時間後、n時間前の時間を求める
function addTimes( inFullTime ,inHours ) {
	//元の日付
	var oDate = inFullTime.substring( 0 ,8 );
	//元の時分
	var oTime = inFullTime.substring( 8 ,12);

	if( !oTime ){ oTime = gantStartTime; }

	//時間の加算
	var resultTime = toHour( oTime ) + inHours;
	var diffDays = 0;
	var overTime = 0;
	var gantDaySpan = toHour( gantEndTime ) - toHour( gantStartTime );

	//後方の日付超える場合
	if( resultTime > toHour( gantEndTime )){
		diffDays = Math.floor( ( resultTime - toHour( gantEndTime )) / gantDaySpan ) + 1;
		overTime = ( resultTime - toHour( gantEndTime )) % gantDaySpan  + toHour( gantStartTime );
	}
	//前方の日付超える場合
	else if( resultTime < toHour( gantStartTime )){
		diffDays = Math.floor(( resultTime - toHour( gantStartTime )) / gantDaySpan );
		overTime = toHour( gantEndTime ) + ( resultTime - toHour( gantStartTime )) % gantDaySpan;
	}
	//日付超えない場合
	else{
		diffDays = 0;
		overTime = resultTime;
	}
	//
	var fgCal = '1'; //カレンダー参照
	var rtnDate = addDays( oDate ,diffDays ,fgCal );
	return rtnDate + toTime( overTime );
}
// 日付からカラム位置を計算する(先頭0）2012/10/01
function dateColumnNo( inDate ) {
	if( inDate == null ){return 0;}
	var diffDay = compareDate( inDate, gantStartDate );
    return Math.floor(diffDay/unitSpan[gantZoom]);
}
// 対象日が休日かどうか 休日ならtrue 2012/10/01
function isHoliday( inDate ){
	var targetClm = dateColumnNo( inDate );
	var rtn = "true";
	if( arrCalender[targetClm] == '1'){ rtn = "true"; }
	else{ rtn = "false"; }
	return rtn;
}
// 対象日の間に休日が何個あるか 2012/10/01
function holidayCount( inDate1, inDate2 ){
	var st = dateColumnNo(inDate1);
	var en = dateColumnNo(addDays( inDate2 ,-1 ,0 ));
	var rtn = 0;
	for( i = st; i <= en; i++ ){
		if( arrCalender[i] == '1'){ rtn++; }
	}
	return rtn;
}

// 日付(YYYYMMDD)の入力欄への反映
function performDateChange( nMyMAction, movedSpan ,fgCal ){
	startDateInputObj = document.getElementById( hilightBar.startDateInput );
	switch ( hilightBar.type ){
		case "0" :
			startDateInputObj.value = addDays( hilightBar.startDT ,movedSpan ,fgCal ) 
			break;
		case "1" :
			endDateInputObj   = document.getElementById( hilightBar.endDateInput );
			switch ( nMyMAction ){
				case cnMLeft :
					startDateInputObj.value = addDays( hilightBar.startDT ,movedSpan ,fgCal ) ;
					break;
				case cnMRight:
					endDateInputObj.value = addDays( hilightBar.endDT ,movedSpan ,fgCal ) ;
					break;
				case cnMMiddle:
					startDateInputObj.value = addDays( hilightBar.startDT ,movedSpan ,fgCal ) ;
					endDateInputObj.value = addDays( hilightBar.endDT ,movedSpan ,fgCal ) 
					break;
				default:
			}
			break;
		default:
	}
}
// 時間（HH24MM）日付(YYYYMMDD)の入力欄への反映
function performTimeChange( nMyMAction, movedSpan ){
	startTimeInputObj = document.getElementById( hilightBar.startTimeInput );
	switch ( hilightBar.type ){
		case "0" :
			var newFullTime = addTimes( hilightBar.startDT ,movedSpan );
			var newDate     = newFullTime.substring( 0 ,8 );
			var newTime     = newFullTime.substring( 8 ,12 );
			var diffDays    = compareDate( newDate ,hilightBar.startDT.substring( 0 ,8) );
			//開始日付の反映
			performDateChange( cnMLeft ,diffDays ,'0');
			//開始時刻の反映
			if( startTimeInputObj ){
				startTimeInputObj.value = newTime;
			}
			break;
		case "1" :
			endTimeInputObj   = document.getElementById( hilightBar.endTimeInput );
			switch ( nMAction ){
				case cnMLeft :
					//開始日付、時刻の計算
					var newFullTime = addTimes( hilightBar.startDT ,movedSpan );
					var newDate     = newFullTime.substring( 0 ,8 );
					var newTime     = newFullTime.substring( 8 ,12 );
					var diffDays    = compareDate( newDate ,hilightBar.startDT.substring( 0 ,8) );
					//開始日付の反映
					performDateChange( cnMLeft ,diffDays ,'0');
					//開始時刻の反映
					startTimeInputObj.value = newTime;
					break;
				case cnMRight:
					//終了日付、時刻の計算
					newFullTime     = addTimes( hilightBar.endDT ,movedSpan );
					var newDate     = newFullTime.substring( 0 ,8 );
					var newTime     = newFullTime.substring( 8 ,12 );
					var diffDays    = compareDate( newDate ,hilightBar.endDT.substring( 0 ,8) );
					//終了日付の反映
					performDateChange( cnMRight ,diffDays ,'0' );
					//終了時刻の反映
					endTimeInputObj.value   = newTime;
					break;
				case cnMMiddle:
					//開始日付、時刻の計算
					var newFullTime = addTimes( hilightBar.startDT ,movedSpan );
					var newDate     = newFullTime.substring( 0 ,8 );
					var newTime     = newFullTime.substring( 8 ,12 );
					var diffDays    = compareDate( newDate ,hilightBar.startDT.substring( 0 ,8) );
					//開始日付の反映
					performDateChange( cnMLeft ,diffDays ,'0' );
					//開始時刻の反映
					startTimeInputObj.value = newTime;
					//終了日付、時刻の計算
					newFullTime     = addTimes( hilightBar.endDT ,movedSpan );
					var newDate     = newFullTime.substring( 0 ,8 );
					var newTime     = newFullTime.substring( 8 ,12 );
					var diffDays    = compareDate( newDate ,hilightBar.endDT.substring( 0 ,8) );
					//終了日付の反映
					performDateChange( cnMRight ,diffDays ,'0' );
					//終了時刻の反映
					endTimeInputObj.value   = newTime;
					break;
				default:
			}
			break;
		default:
	}
}
// 行のチェックをonにする
function setRowChecked(oMyForm, sName, bValue)
{
	var nIndexUp;
	var aInputs=document.getElementsByName(sName);
	if(null != aInputs)
	{
		for(nIndexUp = 0; nIndexUp < aInputs.length;  nIndexUp++ )
		{
			var oSetObj  = aInputs[nIndexUp];
			if(("INPUT" == oSetObj.tagName )
			&& (( "checkbox" == oSetObj.type ) || ( "radio" == oSetObj.type )))
			{
				oSetObj.checked = ((undefined == bValue) ? true : bValue);
			}
		}
	}
}

// ガントバーのドラグドロップ処理
function fnMouseDown( event ){
	hilightBar = event.srcElement;

	if( null != hilightBar )
	{
		var nMyWidth = hilightBar.offsetWidth;

		nLeftRightLimit = Math.min( Math.max( nMyWidth / cnBunkatu, 2 ) ,20 );

		switch ( hilightBar.type ){
			// マイルストーン
			case "0" :
				nMAction = cnMMiddle;
				hilightBar.style.cursor = "move";
				break;
			// バー
			case "1" :
				if( event.offsetX <= nLeftRightLimit ){
					nMAction = cnMLeft;
					hilightBar.style.cursor = "E-resize";
				}
				else if( event.offsetX > ( nMyWidth - nLeftRightLimit )){
					nMAction = cnMRight;
					hilightBar.style.cursor = "E-resize";
				}
				else
				{
					nMAction = cnMMiddle;
					hilightBar.style.cursor = "move";
				}
				break;
			default:
		}

		hilightBar.setCapture();
		startX   = event.screenX;
		oriLeft  = hilightBar.parentNode.offsetLeft;
		oriWidth = hilightBar.width;
	}

}
// ガントバーのドラグドロップ処理
function fnMouseUp( event ){
	if( null != hilightBar )
	{
		hilightBar.style.cursor = "auto";
		hilightBar.releaseCapture();

		if( startDateInputObj ){
			hilightBar.startDT = startDateInputObj.value;
		}
		if( endDateInputObj ){
			hilightBar.endDT   = endDateInputObj.value;
		}
		// 時間の加味
		if( startTimeInputObj ){
			hilightBar.startDT = hilightBar.startDT.substring( 0 ,8 ) + startTimeInputObj.value;
		}
		if( endTimeInputObj ){
			hilightBar.endDT   = hilightBar.endDT.substring( 0 ,8 )   + endTimeInputObj.value;
		}
		//
		nMAction      = cnMNone;
		// 行の選択をonにする
		if(hilightBar.chboxid && ( "" != hilightBar.chboxid)) {
			setRowChecked(null, hilightBar.chboxid);
		}

	}

}

// ガントバーのドラグドロップ処理
function fnMouseMove( event ){
	var moveDist = event.screenX - startX;
	//範囲外の場合処理しない
	if(( nMAction == cnMLeft || nMAction == cnMMiddle ) && hilightBar.parentNode.style.pixelLeft + moveDist < 0){ return false;}
	//
	if(( 1 == event.button ) && ( hilightBar != null )){
		switch ( hilightBar.type ){
			// マイルストーン
			case "0" :
				if( parseInt( gantZoom ,10 ) <= 10 ){
					moveDist = Math.ceil( moveDist / hilightBar.pixelPreSpan ) * hilightBar.pixelPreSpan;
				}
				switch( nMAction ){
					// 中間
					case cnMMiddle:
						hilightBar.parentNode.style.left = parseInt( oriLeft ) + moveDist;
						break;
					default:
				}
				break;
			// バー
			case "1" :
				switch ( nMAction ){
				case cnMLeft :
					if( parseInt( gantZoom ,10 ) <= 10 ){
						moveDist = Math.floor( moveDist / hilightBar.pixelPreSpan ) * hilightBar.pixelPreSpan;
					}
					hilightBar.parentNode.style.left  = parseInt( oriLeft ) + moveDist ;
					hilightBar.width = oriWidth - moveDist;
					break;
				case cnMRight:
					if( parseInt( gantZoom ,10 ) <= 10 ){
						moveDist = Math.ceil( moveDist / hilightBar.pixelPreSpan ) * hilightBar.pixelPreSpan;
					}
					hilightBar.width = oriWidth + moveDist;
					break;
				case cnMMiddle:
					if( parseInt( gantZoom ,10 ) <= 10 ){
						moveDist = Math.ceil( moveDist / hilightBar.pixelPreSpan ) * hilightBar.pixelPreSpan;
					}
					hilightBar.parentNode.style.left = parseInt( oriLeft ) + moveDist;
					break;
				default:
			}
			break;
			default:
		}
		if( parseInt( gantZoom ,10 ) <= 10 ){
			// Change the date
			performDateChange( nMAction, moveDist / hilightBar.pixelPreSpan ,'1');
		}
		else{
			if( hilightBar.startTimeInput != null && hilightBar.startDT.length !=12 ){
				alert( "時間をYYYYMMDDHH24MMのフォーマットで設定してください。("+hilightBar.startDT + ")" );
				return;
			}
			// Change the time & date
			performTimeChange( nMAction, moveDist / hilightBar.pixelPreSpan );
		}
	}
}
// スタックDivに対してガントバーの積上げを行う = 存在しているガントのみ積上げされる 2012/10/01
function costStack( stackRow, gantRow, startDate, endDate, cost ){
	// 対象tbodyが存在するかどうか
	var stackTbody = document.getElementById('stack_'+stackRow);
	if( stackTbody == null || gantRow == null || startDate == null || endDate == null || cost == null){ return false; }
	//開始カラムの取得
	var startNo = dateColumnNo(startDate);
	var endNo = dateColumnNo(endDate);
	var stackDiv;
	var stackList;
	var stackCost;
	
	endDate = addDays( endDate ,1 );
	
	var stackMother = compareDate( endDate, startDate);
	if( stackMother == 0 ){ return false; }
	// 休みの考慮を入れる場合はここで分母から除く。
	if( stackHoliday == "false"){
		stackMother = stackMother - holidayCount(startDate, endDate);
	}
	
	for( i = startNo; i <= endNo; i++ ){
		if( stackHoliday == "false" && arrCalender[i] == '1'){ continue; }
		stackDiv = document.getElementById('stack_' + stackRow + '_' + i);
		if( ! stackDiv ){ continue; }
		stackStart = stackDiv.startdate;
		stackEnd = stackDiv.enddate;
		
		if ( endDate < stackStart || stackEnd < startDate ){ continue; } // 外の分
		
		if( stackDiv.costList == null){
			stackDiv.costList = new Array();
		}
		costList = stackDiv.costList;
		
		var std = (startDate > stackStart) ? startDate : stackStart;
		var end = (endDate < stackEnd) ? endDate : stackEnd;
		
		//積上げコスト計算
		stackCost = cost * compareDate(end,std) / stackMother;
		
		costList["gantt_"+gantRow] = stackCost;
	}
}

// stackのコスト情報の表示 2012/10/01
function viewStack ( tbody ){
	var stackDivs = $(tbody).find('.stackDiv');
	var defaultHeight = stackDivs[0].defHeight;
	var stdCost = tbody.capacity ? tbody.capacity : SYS_STDCOST;
	// 2012/09/26 ADD
	var stackCost = new Array( stackDivs.length );
	var maxRowCost= 0;
	for( i = 0; i < stackDivs.length; i++ ){
		stackCost[i] = 0;
		var costList = stackDivs[i].costList;
		for (j in costList){
			if(costList[j] != null && isFinite(costList[j])){
				stackCost[i] += costList[j];
			}
		}
		// 行の最大コスト値
		if( stackCost[i] > maxRowCost ){ maxRowCost = stackCost[i]; }
	}
	// 2012/09/26 MOD
	for( i = 0; i < stackDivs.length; i++ ){
		//alert(stackDivs[i].nodeName);
		var stdUpper = stdCost * SYS_WARN_BOUND // 2012/09/26 ADD
// 2012/09/26 DEL 行の最大値を計算するため、上に持っていく
//		var stackCost = 0;
//		for (j in costList){
//			if(costList[j] != null && isFinite(costList[j])){
//				stackCost += costList[j];
//			}
//		}
		var newHeight = 0;
		if( viewMode == '1' ){
			newHeight = Math.round( stackCost[i] / maxRowCost * defaultHeight ); // 行の最大値を基準に高さ計算する 2012/09/26 ADD
		}
		else{
			newHeight = Math.round( stackCost[i] / stdCost * defaultHeight * 2 / 3); // 2/3を１の高さにする
		}
		if( newHeight > defaultHeight){
			newHeight = defaultHeight;
		}
		
		stackDivs[i].style.height = newHeight;
		stackDivs[i].style.top = defaultHeight - newHeight;
		
		var stackDiv = $(stackDivs[i]);
		stackDiv.removeClass(SYS_STD_COST);
		stackDiv.removeClass(SYS_UPPER_COST);
		stackDiv.removeClass(SYS_LOWER_COST);
		// 2012/09/26 MOD
		if( stackCost[i] > stdUpper ){
			stackDiv.addClass(SYS_ERROR_COST);
		}
		else if( stackCost[i] < stdCost ){
			stackDiv.addClass(SYS_STD_COST);
		}
		else{
			stackDiv.addClass(SYS_WARN_COST);
		}

		// Costの数字をspanで表示する
		if( stackCost[i] != 0 ){
			stackDiv.html('<span style="width;'+stackDiv.css('width')+'; text-align: center; bottom:0px; font-size: x-small; position: absolute;">'+stackCost[i].toFixed(2)+'</span>');
		}
		
	}
}

// 積上げ部分の作成 2012/10/01
function makeStackBar( gantTd ,strCalender ,lineHeight ){
	if( gantTd == null  ){ return false; }
	//
	iDiv = document.createElement("div");
	gantTd.appendChild( iDiv );
	iDiv.style.position = "relative";
	iDiv.style.height   = lineHeight - 2;
	iDiv.style.width    = "100%";
	iDiv.style.fontSize	="0";

	// 要素のトップ位置
	var iGantPos_Top = ( lineHeight - SYS_BAR_HEIGHT ) / 2 -10;
	
	//横方向にunitPixel分ずつdivを配置していく。
	var iStackDiv 
	for( i = 0; i < strCalender.length; i++ ){
		iStackDiv  = document.createElement("div");
		iStackDiv.className = "stackDiv";
		iStackDiv.style.position = "absolute";
		iStackDiv.style.width = unitPixel[gantZoom];
		iStackDiv.style.height = lineHeight;
		iStackDiv.defHeight = lineHeight;
		iStackDiv.style.left = i*unitPixel[gantZoom];
		iStackDiv.style.top = "0px";
		iStackDiv.id = 'stack_' + gantTd.stackrow + '_' + i;
		
		if( gantZoom != 'MONTH'){
			iStackDiv.startdate = addDays( gantStartDate , unitSpan[gantZoom] * i );
			iStackDiv.enddate = addDays( gantStartDate , unitSpan[gantZoom] * ( i + 1 ) );
		}
		else{
			iStackDiv.startdate = addMonth( gantStartDate, i, 1 );
			iStackDiv.enddate   = addMonth( gantStartDate, i+1, 1 );
		}
		
		iDiv.appendChild( iStackDiv );
	}
}


function showGantBar( gantTd ,listGantBar ,lineHeight ){
	if( gantTd == null || listGantBar == null ){ return false; }
//	// ガントセル幅
//	var unitPixel = {"0" : 48 ,"1" : 24 ,"2" : 12 ,"3" : 56 ,"4" : 56 ,"5" : 90 ,"6" : 60 ,"7" : 90 ,"8" : 90 ,"9" : 60 ,"10": 24 ,"20": 48 ,"21": 24 ,"22": 48 ,"23": 24 ,"24": 48 ,"25": 24 ,"26": 48 ,"27": 24 ,"28": 48 ,"29": 24 ,"30": 48 ,"31": 24 };
//	// ガントセル毎の日数・時間数
//	var unitSpan  = {"0" : 1  ,"1" : 1  ,"2" : 1  ,"3" : 7  ,"4" : 14 ,"5" : 30 ,"6" : 30 ,"7" : 90 ,"8" :180 ,"9" :180 ,"10":  7 ,"20":  1 ,"21":  1 ,"22":  2 ,"23":  2 ,"24":  4 ,"25":  4 ,"26":  6 ,"27":  6 ,"28":  8 ,"29":  8 ,"30": 12 ,"31": 12 };
	// 一日または一時間当たりのピクセル数
	var pixelPreSpan = unitPixel[gantZoom] / unitSpan[gantZoom] ;

	//
	iDiv 	      		= document.createElement("div");
	gantTd.appendChild( iDiv );
	iDiv.style.position = "relative";
	iDiv.style.height   = lineHeight - 2;
	iDiv.style.width    = "100%";
	iDiv.style.left     = SYS_OFFSET_LEFT;
	iDiv.style.fontSize	="0";
	// バー間の上下位置をずらす
	var hPosShift = 10;
	// ガント要素のトップ位置
	var iGantPos_Top = ( lineHeight - SYS_BAR_HEIGHT ) / 2 -10;
	
	// ガント要素毎に描画する。
	while ( listGantBar.hasnext() ){
		var gantBarObj = listGantBar.next();
		//
		var iGantDiv   = document.createElement("div");
		iGantDiv.style.position = "absolute";
		iGantDiv.style.top =iGantPos_Top;
		iGantDiv.stackrow = gantTd.stackrow;
		iGantDiv.ganttrow = gantBarObj.ganttrow;
		
		// 終了日が無い場合はこの月の最終日にする
		if( ! gantBarObj.end ){
			gantBarObj.end = addMonth( gantBarObj.start.substring( 0 ,8 ) , 0, 0 )+ "" + gantBarObj.start.substring( 8 );
		}
		
		// 
		switch( gantBarObj.type ){
			// ガントマーカー
			case "0":
				// 開始終了日付(YYYYMMDD)
				var startDate  = gantBarObj.start.substring( 0 ,8 );
				// 2012/09/27 ADD 開始日が未設定、設定エラーの場合は描画しない
				if( startDate.length == 8 ){
					// 開始終了時間(HH24MM)
					var startTime  = gantBarObj.start.substring( 8 );
					// ガントバーはカレンダー範囲外は描画不能
					if( startDate > gantEndDate ){
						startDate = gantEndDate;
					}
					// 開始日はガント開始日より小さい場合、ガント開始日から描画する
					if( startDate < gantStartDate ){
						startDate = gantStartDate;
					}
					// 開始時間
					if( startTime < gantStartTime ){
						startTime = gantStartTime;
					}
					if( startTime > gantEndTime ){
						startTime = gantEndTime;
					}

					var diffDayS   = compareDate( startDate ,gantStartDate );
					//描画開始、終了位置の計算
					var startPos;
					if( parseInt( gantZoom ,10 ) <= 10 || isNaN(gantZoom)){
						startPos   = diffDayS * pixelPreSpan;
					}
					else{
						// 休日を飛ばす場合	
						var countHoliday = 0;
						if( skipHoliday == "true" ){
							// 
							countHoliday = 0;
							for( var i = 0 ; i < diffDayS ;i++ ){
								if( arrCalender[i] > 0 ){ countHoliday++; }
							}
							diffDayS -= countHoliday;
						}
						// 描画開始位置 = 日付差分(開始日) + 時間差分(開始時間)
						startPos   = diffDayS * Math.ceil( hoursPreDay / unitSpan[gantZoom] ) * unitPixel[gantZoom] +
									 ( parseInt( startTime.substring( 0 ,2 ) ,10 ) - parseInt( gantStartTime.substring( 0 ,2 ) ,10 ) + 
									 ( parseInt( startTime.substring( 2    ) ,10 ) - parseInt( gantStartTime.substring( 2    ) ,10 )) / 60 ) * pixelPreSpan;
					}
					iGantDiv.style.left= startPos;

					var iCenter    = document.createElement("img");
					iCenter.src    = gantBarObj.src;
					// ツールチップの表示 2012/09/27 MOD 日単位の場合、時間表示しない
					if( parseInt( gantZoom ,10 ) >= 20 ){
						iCenter.alt = startDate.substring( 0 ,4 ) + "/" + startDate.substring( 4 ,6 ) + "/" + startDate.substring( 6 ,8 ) 
										+ " " + startTime.substring( 0 ,2 ) + ":" + startTime.substring( 2 ,4 )
									  ;
					}
					else {
						iCenter.alt = startDate.substring( 0 ,4 ) + "/" + startDate.substring( 4 ,6 ) + "/" + startDate.substring( 6 ,8 ) ;
					}
					// ガントバーの移動対応
					if((document.getElementById( gantBarObj.startDateInput ) && gantBarObj.startDateInput != null ) ||
					   (document.getElementById( gantBarObj.startTimeInput ) && gantBarObj.startTimeInput != null )){
						// 値連動用のパラメータ
						iCenter.type         = gantBarObj.type;
						iCenter.startDT      = gantBarObj.start;
						iCenter.startDateInput   = gantBarObj.startDateInput;
						iCenter.startTimeInput   = gantBarObj.startTimeInput;
						iCenter.pixelPreSpan = pixelPreSpan;
						iCenter.chboxid      = gantBarObj.chboxid;
						iCenter.attachEvent( "onmousedown"  , function(){ fnMouseDown( event );} );
						iCenter.attachEvent( "onmousemove"  , function(){ fnMouseMove( event );} );
						iCenter.attachEvent( "onmouseup"    , function(){ fnMouseUp(   event );} );
					}

					// 
					iGantDiv.appendChild( iCenter );
					//
					iGantDiv.style.top = iGantPos_Top * 1 + SYS_MARKER_OFFSET_H;
				}
				break;
			// ガントバー
			case "1":
				// バーを縦方向でずらして描画
				if( verticalShift == "true" ){
					hPosShift = hPosShift == -SYS_BAR_HEIGHT/2 ? SYS_BAR_HEIGHT/2 : -SYS_BAR_HEIGHT/2;
				}
				else{
					hPosShift = 0;
				}
				iGantPos_Top = ( lineHeight - SYS_BAR_HEIGHT ) / 4 + hPosShift;
				iGantDiv.style.top = iGantPos_Top;

				// 開始終了日付(YYYYMMDD)
				var startDate  = gantBarObj.start.substring( 0 ,8 );
				var endDate    = gantBarObj.end.substring( 0 ,8 );
				var endDate2   = gantBarObj.end.substring( 0 ,8 );
				// 開始終了時間(HH24MM)
				var startTime  = gantBarObj.start.substring( 8 );
				var endTime    = gantBarObj.end.substring( 8 );
				// 開始日と終了日逆転は描画不能
				if( startDate > endDate ){
					break;
				}
				// ガントバーはカレンダー範囲外は描画不能
				if( startDate > gantEndDate || endDate < gantStartDate ){
					break;
				}
				// 終了時間は開始時間より小さい場合、終了日は次の日で計算する。（夜勤の場合）
				if( endTime < startTime ){
					endDate = addDays( endDate ,1 );
				}
				endDate = addDays( endDate ,1 );
				// 開始日はガント開始日より小さい場合、ガント開始日から描画する
				if( startDate < gantStartDate ){
					startDate = gantStartDate;
				}
				// 終了日はガント終了日より多きい場合、ガント終了日まで描画する
				if( endDate > gantEndDate ){
					endDate = gantEndDate;
				}
				// 開始時間
				if( startTime < gantStartTime ){
					startTime = gantStartTime;
				}
				if( startTime > gantEndTime ){
					startTime = gantEndTime;
				}
				// 終了時間
				if( endTime > gantEndTime ){
					endTime = gantEndTime;
				}
				if( endTime < gantStartTime ){
					endTime = gantStartTime;
				}

				var diffDayS   = compareDate( startDate ,gantStartDate );
				var diffDayE   = compareDate( endDate   ,gantStartDate );
				//描画開始、終了位置の計算
				var startPos;
		        var endPos  ;
				if( parseInt( gantZoom ,10 ) <= 10 || isNaN(gantZoom) ){
					startPos   = diffDayS * pixelPreSpan;
					endPos     = diffDayE * pixelPreSpan;
				}
				else{
					// 休日を飛ばす場合	
					var countHoliday = 0;
					if( skipHoliday == "true" ){
						// 
						countHoliday = 0;
						for( var i = 0 ; i < diffDayS ;i++ ){
							if( arrCalender[i] > 0 ){ countHoliday++; }
						}
						diffDayS -= countHoliday;
						// 
						countHoliday = 0;
						for( var i = 0 ; i < diffDayE ;i++ ){
							if( arrCalender[i] > 0 ){ countHoliday++; }
						}
						diffDayE -= countHoliday;
					}
					// 描画開始位置 = 日付差分(開始日) + 時間差分(開始時間)
					startPos   = diffDayS * Math.ceil( hoursPreDay / unitSpan[gantZoom] ) * unitPixel[gantZoom] +
								 ( parseInt( startTime.substring( 0 ,2 ) ,10 ) - parseInt( gantStartTime.substring( 0 ,2 ) ,10 ) + 
								 ( parseInt( startTime.substring( 2    ) ,10 ) - parseInt( gantStartTime.substring( 2    ) ,10 )) / 60 ) * pixelPreSpan;
					// 描画終了位置 = 日付差分(終了日) + 時間差分(終了時間)
					endPos     = ( diffDayE - 1 ) * Math.ceil( hoursPreDay / unitSpan[gantZoom] ) * unitPixel[gantZoom] + 
								 ( parseInt( endTime.substring( 0 ,2 ) ,10 ) - parseInt( gantStartTime.substring( 0 ,2 ) ,10 ) + 
								 ( parseInt( endTime.substring( 2    ) ,10 ) - parseInt( gantStartTime.substring( 2    ) ,10 )) / 60 ) * pixelPreSpan;
				}
				iGantDiv.style.left= startPos;
				
				// 表示しない場合は以下処理しない
				if(viewGantt == "true"){

					var iCenter    = document.createElement("img");
					//ガント図の元画像
					switch( gantBarObj.color ){
						case "blue":
							iCenter.src    = "../image/W_blue.png";
							break;
						case "lightblue":
							iCenter.src    = "../image/W_lightblue.png";
							break;
						case "green":
							iCenter.src    = "../image/W_green.png";
							break;
						case "lightgreen":
							iCenter.src    = "../image/W_lightgreen.png";
							break;
						case "red":
							iCenter.src    = "../image/W_red.png";
							break;
						case "pink":
							iCenter.src    = "../image/W_pink.png";
							break;
						case "orange":
							iCenter.src    = "../image/W_orange.png";
							break;
						case "brown":
							iCenter.src    = "../image/W_brown.png";
							break;
						case "purple":
							iCenter.src    = "../image/W_purple.png";
							break;
						case "black":
							iCenter.src    = "../image/W_black.png";
							break;
						case "black2":
							iCenter.src    = "../image/W_black2.png";
							break;
						case "yellow":
							iCenter.src    = "../image/W_yellow.png";
							break;
						case "violet":
							iCenter.src    = "../image/W_violet.png";
							break;
						case "navy":
							iCenter.src    = "../image/W_navy.png";
							break;
						case "glay":
							iCenter.src    = "../image/W_glay.png";
							break;
						case "darkgreen":
							iCenter.src    = "../image/W_darkgreen.png";
							break;
						case "teal":
							iCenter.src    = "../image/W_teal.png";
							break;
						case "indigo":
							iCenter.src    = "../image/W_indigo.png";
							break;
						case "chocorlate":
							iCenter.src    = "../image/W_chocorlate.png";
							break;
						case "slategray":
							iCenter.src    = "../image/W_slategray.png";
							break;
						case "darkslategray":
							iCenter.src    = "../image/W_darkslategray.png";
							break;
						default:
							iCenter.src    = "../image/W_Blue.png";
							break;
					}
					iCenter.width  = endPos - startPos;
					iCenter.height = SYS_BAR_HEIGHT;

					// ツールチップの表示 2012/09/27 MOD 日単位の場合、時間表示しない
					if( parseInt( gantZoom ,10 ) >= 20 ){
						iCenter.alt = startDate.substring( 0 ,4 ) + "/" + startDate.substring( 4 ,6 ) + "/" + startDate.substring( 6 ,8 ) 
										+ " " + startTime.substring( 0 ,2 ) + ":" + startTime.substring( 2 ,4 ) + "-" + 
									  endDate2.substring( 0 ,4 )   + "/" + endDate2.substring( 4 ,6 )   + "/" + endDate2.substring( 6 ,8 )
										+ " " + endTime.substring( 0 ,2 ) + ":" + endTime.substring( 2 ,4 )
									  ;
					}
					else {
						iCenter.alt = startDate.substring( 0 ,4 ) + "/" + startDate.substring( 4 ,6 ) + "/" + startDate.substring( 6 ,8 ) + "-" + 
									   endDate2.substring( 0 ,4 ) + "/" +  endDate2.substring( 4 ,6 ) + "/" +  endDate2.substring( 6 ,8 );
					}
					// 
					iGantDiv.appendChild( iCenter );
					// ガントバーの移動対応
					if(( document.getElementById( gantBarObj.startDateInput ) && gantBarObj.startDateInput != null  &&
						 document.getElementById( gantBarObj.endDateInput   ) && gantBarObj.endDateInput   != null ) ||
					   ( document.getElementById( gantBarObj.startTimeInput ) && gantBarObj.startTimeInput != null  &&
						 document.getElementById( gantBarObj.endTimeInput   ) && gantBarObj.endTimeInput   != null ) ){
						// 値連動用のパラメータ
						iCenter.type         = gantBarObj.type;
						iCenter.startDT      = gantBarObj.start;
						iCenter.endDT        = gantBarObj.end;
						iCenter.startDateInput   = gantBarObj.startDateInput;
						iCenter.startTimeInput   = gantBarObj.startTimeInput;
						iCenter.endDateInput     = gantBarObj.endDateInput;
						iCenter.endTimeInput     = gantBarObj.endTimeInput;
						iCenter.pixelPreSpan = pixelPreSpan;
						iCenter.chboxid      = gantBarObj.chboxid;
						iCenter.attachEvent( "onmousedown"  , function(){ fnMouseDown( event );} );
						iCenter.attachEvent( "onmousemove"  , function(){ fnMouseMove( event );} );
						iCenter.attachEvent( "onmouseup"    , function(){ fnMouseUp(   event );} );
					}

					// 改行
					var iBr    = document.createElement("br");
					iGantDiv.appendChild( iBr );
				}
			
		}
		// 注釈
		iGantDiv.style.fontSize	="12";
		// リンク追加 2012/09/27 ADD
		if( gantBarObj.href ){
			var linkObj = document.createElement("a");
			linkObj.href   = gantBarObj.href;
			linkObj.target = gantBarObj.target ? gantBarObj.target : SYS_LINK_TARGET;
			var linkMsg = document.createTextNode( gantBarObj.msg );
			linkObj.appendChild(linkMsg);
			iGantDiv.appendChild( linkObj );
		}
		else {
			// 注釈をガント要素の下方に表示させる
			iGantDiv.appendChild( document.createTextNode( gantBarObj.msg ));
		}

		// 
		iDiv.appendChild( iGantDiv );
		// 工数を積み上げる
		if( gantBarObj.type == '1' && gantBarObj.cost ){
			costStack( iGantDiv.stackrow, iGantDiv.ganttrow, gantBarObj.start.substring( 0 ,8 ), gantBarObj.end.substring( 0 ,8 ), gantBarObj.cost );
		}
	}
}

// メイン処理（画面から呼び出す）
function adjustGant(){
	// viewTableのオブジェクトの取得
	var viewTableObj = document.getElementById( "viewTable" );
	// viewTableが存在しなければ終了
	if( viewTableObj == null ){ return false; } 

	// ganttHeaderオブジェクトの取得
	var gantHeaderObj = document.getElementById( "ganttHeaderData" );
	// gantHeaderObjが存在しなければ終了
	if( gantHeaderObj == null ){ return false; }

	// iGantオブジェクト取得
	var iGantObjs = document.getElementsByTagName( "iGant" );
	// iGantObjsが存在しなければ終了
	if( iGantObjs == null || iGantObjs.length == 0 ){ return false; }

	// 休憩時間の網掛けを非表示（高さ調整前）
	$(".breaktime").hide();
	// カレンダーの文字列
	var strCalender   = gantHeaderObj.calDB;
	// 描画可能なズーム
	var gantZooms = ["0","1","2","3","4","5","6","7","8","9","10","20","21","22","23","24","25","26","27","28","29","30","31"
						,"DAY","WEEK","MONTH"];
	// 属性値の取得
	// ガントズーム
	gantZoom      = gantHeaderObj.zoom;
	// ガントの描画開始日付(時間)
	gantStartDate = gantHeaderObj.startDate;
	gantEndDate   = gantHeaderObj.endDate;
	// 一日の描画時間数(0700-2000)
	daySpan		  = gantHeaderObj.daySpan;
	// 休日を飛ばすか
	skipHoliday   = gantHeaderObj.skipHoliday;
	// stack関係 2012/10/01
// 2012/09/26 DEL
//	stdUpper 	  = iGantObjs[0].stdUpper ? iGantObjs[0].stdUpper : stdUpper;
//	stdCost 	  = iGantObjs[0].stdCost ? iGantObjs[0].stdCost : stdCost;
//	stdLower 	  = iGantObjs[0].stdLower ? iGantObjs[0].stdLower : stdLower;
	viewGantt	  = iGantObjs[0].viewGantt ? iGantObjs[0].viewGantt : viewGantt;	// 2012/09/26 ADD
	viewMode	  = iGantObjs[0].viewMode ? iGantObjs[0].viewMode : viewMode;		// 2012/09/26 ADD
	stackHoliday  = iGantObjs[0].stackHoliday ? iGantObjs[0].stackHoliday : stackHoliday;
	// 複数行のマージ
	margeRows 	  = iGantObjs[0].margeRows;
	// 縦方向でずらすか
	verticalShift = ( iGantObjs[0].verticalShift != null  ) ? iGantObjs[0].verticalShift : verticalShift;
	// 固定列
	fixedCols 	  = iGantObjs[0].fixedCols;
	// 縞々背景色の使用 2012/09/26 add
	useBgColor 	  = ( iGantObjs[0].useBgColor != null ) ? iGantObjs[0].useBgColor : useBgColor;

	// viewTableに番号列が表示されるか
	viewNumberType	  = iGantObjs[0].viewNumberType;

	// 必須属性のチェック、設定していなければ終了
	if( gantZoom == null || gantStartDate == null || gantEndDate == null || daySpan == null ){ return false; }
	// gantZoomのチェック
	if( !gantZooms.contains( gantZoom ) ){ return false; }

	// 始業時間(0700-xxxx)
	gantStartTime	  = daySpan.split("-")[0];
	// 終業時間(xxxx-2000)
	gantEndTime	  	  = daySpan.split("-")[1];
	// 終業時間が大きい場合、始業時間と終業時間ともに同日の時間で計算する
	if( gantEndTime > gantStartTime ){
		hoursPreDay = parseInt( gantEndTime.substring( 0 ,2 ) ,10 ) - parseInt( gantStartTime.substring( 0 ,2 ) ,10 ) + 
					( parseInt( gantEndTime.substring( 2    ) ,10 ) - parseInt( gantStartTime.substring( 2    ) ,10 )) / 60;
	}
	// 始業時間が大きい場合、始業時間は終業時間の次の日の時間として計算する(夜勤)
	else{
		hoursPreDay = 24 + 
					  parseInt( gantStartTime.substring( 0 ,2 ) ,10 ) - parseInt( gantEndTime.substring( 0 ,2 ) ,10 ) + 
					( parseInt( gantStartTime.substring( 2    ) ,10 ) - parseInt( gantEndTime.substring( 2    ) ,10 )) / 60;
	}
	// カレンダー解析（パス）
	if( skipHoliday == "true" || stackHoliday == "false" ){
		calenderDays = strCalender.length;
		arrCalender = new Array( calenderDays );
		for( i = 0 ;i < calenderDays ;i++ ){
			arrCalender[i] = strCalender.substr( i ,1 );
		}
	}

	// viewTableよりデータノードを作成する。
	// theadオブジェクトの取得（一つしかない）
	var headerObjs   = viewTableObj.all.tags("THEAD");
	// theadにタイトルの物理的な行数
	var tHeadLines   = headerObjs[0].all.tags("TR").length;
	//
	var bodyHeight = 0;
	
	// tbodyオブジェクトの取得（業務データの一行分）
	var tBodyObjs   = viewTableObj.all.tags("TBODY");
	var countTBody = tBodyObjs.length;
	// tbodyに業務データの物理的な行数
	var countLines = tBodyObjs[0].all.tags("TR").length;
	// tbody毎のセル数
	var countCells = tBodyObjs[0].all.tags("TD").length;
	// 業務データ行(tBody)の高さ
	var lineHeight = tBodyObjs[0].offsetHeight;
	// ２段組でガントバーを上下シフトして表示させる
	if( verticalShift == "true" ){
		if( lineHeight < SYS_MIN_HEIGHT_SHIFT    ){ lineHeight = SYS_MIN_HEIGHT_SHIFT; }
	}
	else{
		if( lineHeight < SYS_MIN_HEIGHT_NO_SHIFT ){ lineHeight = SYS_MIN_HEIGHT_NO_SHIFT; }
	}

	// ガント要素のリスト
	// 描画の行単位でキャッシュする、行マージする場合はマージ後の行となる
	var listGantBar = new List();
	// 前後行のデータ
	var cellValPre  = new Array( countCells );
	var cellValNext = new Array( countCells );
	// 前後行の比較結果（0:同様(マージできる) 1:同様じゃない(マージできない)）
	var fgDiff      = 0;
	var gantTd		= null;
	// tBodyの数分ループ（業務データの一行(tBody)ずつ描画させる）
	for( var i = 0; i < countTBody; i++ ){
		// ガント要素のリスト
		// 業務データの行単位(tBody)のガント要素をキャッシュする。行マージする場合はマージ前の行となる
		var swapGantBar = new List();
		// 業務データの行(tBody)毎のセル
		var lineTdObjs = tBodyObjs[i].all.tags("TD");
		// ガント要素の親TD
		var swapGantTd = null;
		// stack判定 2012/10/01
		var stackTbody = tBodyObjs[i].stackline;
		var stackrow = tBodyObjs[i].stackrow;
		for( var j = 0; j < countCells; j++ ){
			// 前方の行番号など、比較対象外
			if( j < SYS_NUMBER_CELLS && viewNumberType !='delete' ){
				cellValNext[j] = "";
			}
			// ガント要素、比較対象外
			else if( lineTdObjs[j].firstChild && lineTdObjs[j].firstChild.tagName == "IGANTBAR" ){
				var childObjs = lineTdObjs[j].childNodes;
				// 
				for( var k = 0; k < childObjs.length; k++ ){
					childObjs[k].ganttrow = i; // 2012/10/01
					swapGantBar.add( childObjs[k] );
					// 2012/09/26 ADD
					if( childObjs[k].capacity && parseInt( childObjs[k].capacity ,10 ) > 0 ){
						document.getElementById('stack_' + tBodyObjs[i].stackrow ).capacity = childObjs[k].capacity;
					//	$("#stack_"+).attr("capacity" ,childObjs[k].capacity);
					}
				}
				cellValNext[j] = "";
				swapGantTd = lineTdObjs[j];
				swapGantTd.stackrow = stackrow; // 2012/10/01
			}
			else{
				cellValNext[j] = lineTdObjs[j].innerHTML;
			}
		}
		// 前行の初期値
		if( i == 0 ){
			cellValPre = cellValNext.clone();
			if( stackTbody == "true" ){ // 2012/10/01
				makeStackBar( swapGantTd ,strCalender ,lineHeight );
				listGantBar.head = null;
				listGantBar.size = 0;
			}
			else{
				gantTd     = swapGantTd;
				// ガント要素を描画リストに追加
				while ( swapGantBar.hasnext() ){
					listGantBar.add( swapGantBar.next() );
				}
			}
		}
		else{
			// 行のマージを行う場合
			if( margeRows == "true" ){
				// 前後行データの比較
				fgDiff = 0;
				for( var j = 0; j < countCells; j++ ){
					if( cellValPre[j] != cellValNext[j] ){
						cellValPre = cellValNext.clone();
						// 不一致あり
						fgDiff = 1;
						break;
					}
				}
			}
			// 行のマージを行わない場合
			else{
				fgDiff = 1;
			}
			// 
			if( fgDiff == 1 ){
				// ガント要素の出力
				bodyHeight += lineHeight + 2;
				if( stackTbody == "true" ){ // 2010/10/01
					//gantTd = swapGantTd;
					makeStackBar( swapGantTd ,strCalender ,lineHeight );
					listGantBar.head = null;
					listGantBar.size = 0;
				}
				else{
					// ガント要素の描画
					showGantBar( gantTd ,listGantBar ,lineHeight );
					// リスト削除
					listGantBar.head = null;
					listGantBar.size = 0;

					// 
					gantTd = swapGantTd;
					// ガント要素を描画リストに追加
					while ( swapGantBar.hasnext() ){
						listGantBar.add( swapGantBar.next() );
					}
				}
			}
			// マージされるため、行要素の削除
			else{
				// ガント要素を描画リストに追加
				while ( swapGantBar.hasnext() ){
					listGantBar.add( swapGantBar.next() );
				}
				tBodyObjs[i].parentNode.removeChild( tBodyObjs[i] );
				i--;
				countTBody--;

			}
		}
	}
	// 2012/09/25 ADD 背景色のリセット
	var countTBody = tBodyObjs.length;
	if( useBgColor == 'true' ){
		for( i = 0 ;i < countTBody ;i++ ){
			tBodyObjs[i].className = "row_" + i%2;
		}
	}
	// 2012/09/25 ADD 行番号のリセット
	if( viewNumberType != 'delete' ){
		for( i = 0 ;i < countTBody ;i++ ){
			tBodyObjs[i].all.tags("TD")[2].innerText = i + 1;
		}
	}

	// 最後一行の出力
	bodyHeight += lineHeight + 2;
	// ガント要素の描画
	showGantBar( gantTd ,listGantBar ,lineHeight );
	//ガント描画不要の場合 2010/10/01
	if ( viewGantt  == 'false' ){
		$("tbody[stackline=false]").hide();
	}
	else if( viewGantt == 'expand' ){
		$("tbody[stackline=false]").hide();
		// 展開表示のための処理を行う場合はここに入れるが、ガントの表示の考慮必要
	}
	
	// リスト削除
	listGantBar.head = null;
	listGantBar.size = 0;
	//
	var headSpanObjs = headerObjs[0].all.tags("SPAN");
	var countBreakTimeSpan = 0;
	for( var i = 0; i < headSpanObjs.length; i++ ){
		if( headSpanObjs[i].className == "breaktime" ) countBreakTimeSpan++;
	}

	// breakTimeの調整
	var spanObjs = viewTableObj.all.tags("SPAN");
	var indexBreakTimeSpan = 0;
	if( spanObjs != null ){
		for( var i = 0 ;i < spanObjs.length ;i++  ){
			if( spanObjs[i].className == "breaktime" ){
				indexBreakTimeSpan++;
				if( indexBreakTimeSpan <= countBreakTimeSpan ){
					spanObjs[i].style.height = bodyHeight;
				}
				else{
					spanObjs[i].style.height = 0;
				}
			}
		}
	}
	
	// 積上げ部分の描画を行う 2010/10/01
	tBodyObjs   = viewTableObj.all.tags("TBODY");
	countTBody = tBodyObjs.length;
	for( i = 0; i < countTBody; i++ ){
		if( tBodyObjs[i].stackline == 'true' ){
			viewStack(tBodyObjs[i]);
		}
	}
	

	//固定列数が設定される場合、テーブルの２分割処理を行う。
	if( fixedCols > 0 ){
		// 二分割の処理を行う。
		makeSuperTable( "viewTable" ,fixedCols );
	
	}
	// 休憩時間の網掛けを表示させる（高さ調整済）
	$(".breaktime").show();
};

/* version: 0.0.1 
 * author : Sen Li
 * date   : 2012/05/10
 * 機能   : テーブルの左右2分割処理
 */

// セルの位置情報( 行 ,列 )
function cellNode( inRow ,inCol ){ 
	this.row   = inRow;
	this.col   = inCol;
}
// テーブル２分割処理
function makeSuperTable( viewTableId, fixedCols ) {
	// 初期化
	var scrollBarWidth  = 16;
	var scrollBarHeight = 20;
	// 左側の固定列数（初期値：0）
	fixedCols = parseInt( fixedCols || "0" );
	// 各列の幅
	colWidths = [];
	
	// 各枠のDIV要素作成
	ourterDiv = document.createElement( "DIV" );

	// ヘッダーの固定部
	fixedHeaderDiv  = ourterDiv.cloneNode( false );

	// ヘッダーのスクロール部分のベース枠
	scrollHeaderBaseDiv = ourterDiv.cloneNode( false );

	// ヘッダーのスクロール部分の枠
	scrollHeaderDiv = ourterDiv.cloneNode( false );

	// ボディの左固定部分のベース枠
	fixBodyBaseDiv = ourterDiv.cloneNode( false );

	// ボディの左固定部分の枠
	fixBodyDiv = ourterDiv.cloneNode( false );

	// ボディの右スクロール部分の枠
	scrollBodyDiv = ourterDiv.cloneNode( false );

	// ボディの右スクロール部分のテーブル
	scrollBodyTable = document.getElementById( viewTableId );
	// viewTableが存在しなければ終了
	if( scrollBodyTable == null ){ return false; }
	// 元のテーブルの縦横幅の取得
	var tableWidth  = scrollBodyTable.offsetWidth;
	var tableHeight = scrollBodyTable.offsetHeight;

	var sHeaderHeight;
	var tHead = scrollBodyTable.tHead;

	if( tHead ){
		sHeaderHeight = tHead.offsetHeight;
	}
	else{
		sHeaderHeight = scrollBodyTable.tBody[0].offsetHeight;
	}

	if( scrollBodyTable == null || fixedCols <= 0 ){ return true; }

	// スタイルの設定
	// -----------------------------------------------------
	// 外枠のスタイル
	ourterDiv.id		= "ourterDiv";
	// ヘッダーの固定部
	fixedHeaderDiv.id 	= "fixedHeaderDiv";
	// ヘッダーのスクロール部分のベース枠
	scrollHeaderBaseDiv.id = "scrollHeaderBaseDiv";
	// ヘッダーのスクロール部分の枠
	scrollHeaderDiv.id	   = "scrollHeaderDiv";
	// ボディの左固定部分のベース枠
	fixBodyBaseDiv.id	   = "fixBodyBaseDiv";
	// ボディの左固定部分の枠
	fixBodyDiv.id		   = "fixBodyDiv";
	// ボディの右スクロール部分の枠
	scrollBodyDiv.id	   = "scrollBodyDiv";

	// -----------------------------------------------------
	// カラムスタイル
	colGroupStyle    = document.createElement("COLGROUP");

	// IE幅
	var windowWidth  = getClientWidth();
	// テーブルのトップ位置
	var tableTop= scrollBodyTable.offsetTop;

	// IEの高さ
	var windowHeight = getClientHeight();
	// 
	// テーブルの実レイアウトによりCOLGROUPを作成するため、既存のCOLGROUPを削除する。
	for( i = scrollBodyTable.getElementsByTagName( "COLGROUP" ).length-1 ;i >= 0 ;i-- ){
		scrollBodyTable.removeChild( scrollBodyTable.getElementsByTagName( "COLGROUP" )[i] );
	}
	// 
	sParent 		 = scrollBodyTable.parentNode;
	sParentHeight 	 = sParent.offsetHeight;
	sParentWidth 	 = sParent.offsetWidth;
	
	// スワップ変数
	var alpha, beta, i, j;
	// ヘッダーのスクロール部分のテーブル作成
	scrollHeaderTable = scrollBodyTable.cloneNode( false );
	// ヘッダーのスクロール部分のテーブルのスタイル設定
	scrollHeaderTable.id ="scrollHeaderTable" ;

	// 元のテーブルにtHeadが存在すれば、そのtHeadをコピーする。
	if( tHead ) {
		alpha = tHead;
		// ヘッダーのスクロール部分のテーブル作成
		scrollHeaderTable.appendChild( alpha.cloneNode( true ));
	} else {
		alpha = scrollBodyTable.tBodies[0];
		scrollHeaderTable.appendChild( alpha.cloneNode( true ));
	}

	// ヘッダーのスクロール部分のテーブルをDIVに入れる。
	scrollHeaderDiv.appendChild( scrollHeaderTable );
	
	fixedHeaderTable = scrollHeaderTable.cloneNode( true );
	// スタイル設定
	fixedHeaderTable.id = "fixedHeaderTable";

	fixedHeaderDiv.appendChild(fixedHeaderTable);
	// ボディの左固定部のテーブル

	fixedBodyTable = scrollBodyTable.cloneNode( true );
	// ボディの左固定部のテーブルのスタイル
	fixedBodyTable.id = "fixedBodyTable";
	fixBodyDiv.appendChild( fixedBodyTable );
	
	// カラムスタイルの設定
	var tBodyRows       = scrollBodyTable.tBodies[0].rows;
	var tBodyRowsLength = tBodyRows.length;
	var maxCellRow      = 0;
	var countRowCells   = 0;

	// クリティカルパスの作成準備
	var cellColSpan     = 0;
	var cellRowSpan     = 0;
	var countSingleCol  = 0;
	var colLength       = tBodyRows[0].cells.length;
	for( i = 0; i < colLength; i++ ){
		countSingleCol += tBodyRows[0].cells[i].colSpan;
	}
	// 
	var cellGridMap     = new Array( tBodyRowsLength );

	// 行毎のセル番号のキャッシュ
	var colIndex = new Array( tBodyRowsLength );
	for( rowId = 0; rowId < tBodyRowsLength; rowId++ ){
		cellGridMap[rowId] = new Array( countSingleCol );
		colIndex[rowId]=0;
	}
	// cellGridMapの作成
	for( rowId = 0; rowId < tBodyRowsLength; rowId++ ){
		colLength    = tBodyRows[rowId].cells.length;
		for( colId = 0; colId < colLength; colId++ ){
			cellRowSpan = tBodyRows[rowId].cells[colId].rowSpan;
			cellColSpan = tBodyRows[rowId].cells[colId].colSpan;
			for( j = 0 ;j < cellColSpan ;j++ ){
				for( i = 0 ;i < cellRowSpan ;i++ ){
					// 空セルを探す。
					for( m =0 ;m < countSingleCol; m++ ){
						if( cellGridMap[rowId + i][ colIndex[rowId]] != null ) colIndex[rowId]++;
					}
					// セル情報のキャッシュ
					cellGridMap[rowId + i][ colIndex[rowId] ] = new cellNode( rowId ,colId );
				}
				colIndex[rowId]++;
			}

		}
	}
	// クリティカルパスの作成
	var keyCells = [];
	var index    = 0;
	for( j = 0 ;j < countSingleCol ;j++ ){
		for( i = 0 ;i < tBodyRowsLength ;i++ ){
			cellColSpan = tBodyRows[ cellGridMap[i][j].row ].cells[ cellGridMap[i][j].col ].colSpan;
			if( cellColSpan == 1 ){
				keyCells[index] = new cellNode( cellGridMap[i][j].row ,cellGridMap[i][j].col );
				index++
				break;
			}
		}
	}

	// クリティカルパスにより、各列の幅を取得する。
	for( i=0; i < countSingleCol; i++){
		colWidths[i] = tBodyRows[ keyCells[i].row ].cells[ keyCells[i].col ].offsetWidth;
	}

	// colspanによる幅の誤差計算
	var fixedDivDiff = 0;
	var totalDiff    = 0;
	index = 0;
	// 誤差計算
	for( i = 0 ; i < countSingleCol ;i++ ){
		if( colWidths[i] > SYS_CELLPADDING ){
			colWidths[i] -= SYS_CELLPADDING;
		}
		else{
			if( i < fixedCols ){
				fixedDivDiff += SYS_CELLPADDING * 1;
			}
			totalDiff        += SYS_CELLPADDING * 1;
		}
		i += tHead.rows[0].cells[index++].colSpan - 1 ;
	}

	// 誤差を加味する。
	var fixedHeaderDivWidth = tBodyRows[ keyCells[fixedCols].row ].cells[ keyCells[fixedCols].col ].offsetLeft + fixedDivDiff;

	// カラムスタイルを一致させる
	for( i = 0, j = colWidths.length; i < j; i++ ){
		colGroupStyle.appendChild( document.createElement( "COL" ));
		colGroupStyle.lastChild.setAttribute( "width", colWidths[i] );
	}

	// ボディ部のスクロールテーブル
	scrollBodyTable.insertBefore(    colGroupStyle.cloneNode( true ), scrollBodyTable.firstChild   );
	// ヘッダー部のスクロールテーブル
	scrollHeaderTable.insertBefore(  colGroupStyle.cloneNode( true ), scrollHeaderTable.firstChild );
	// ボディの固定部分
	fixedBodyTable.insertBefore(     colGroupStyle.cloneNode( true ), fixedBodyTable.firstChild    );
	// ヘッダーの固定部分
	fixedHeaderTable.insertBefore(   colGroupStyle.cloneNode( true ), fixedHeaderTable.firstChild  );
	
	// 画面に外枠(ourterDiv)の出力
	sParent.insertBefore( ourterDiv, scrollBodyTable );

	// ヘッダーの固定部を外枠(ourterDiv)に入れる
	ourterDiv.appendChild( fixedHeaderDiv );
	// 
	scrollHeaderBaseDiv.appendChild( scrollHeaderDiv );
	// ヘッダーのスクロール部を外枠(ourterDiv)に入れる
	ourterDiv.appendChild( scrollHeaderBaseDiv );

	// ボディの固定部を外枠(ourterDiv)に入れる
	ourterDiv.appendChild( fixBodyBaseDiv );

	fixBodyBaseDiv.appendChild( fixBodyDiv );
	// ボディのスクロール部を外枠(ourterDiv)に入れる
	ourterDiv.appendChild( scrollBodyDiv );

	scrollBodyDiv.appendChild( scrollBodyTable );

	//スクロール部分の入力欄を無効にする 2012/09/05 ADD
	var scrollInputObjs = scrollBodyTable.getElementsByTagName("input")
	var cnt = scrollInputObjs.length;
	while( --cnt>=0 ) {
		scrollInputObjs[cnt].setAttribute("disabled" ,"true");
	}

	// 左固定部の幅を設定する。
	fixedHeaderDiv.style.width = fixedHeaderDivWidth + "px";
	
	// テーブルのスタイル設定
	var scrollBodyDivStyles, scrollBodyTableStyles;

	scrollBodyTableStyles = "margin-top: " + ( sHeaderHeight * -1 ) + "px;";
	scrollBodyDivStyles   = "margin-top: " +   sHeaderHeight + "px;";

	// テーブル幅のトータル誤差を加味する。
	tableWidth = tableWidth + totalDiff;
	var ourterDivWidth = ( tableWidth  + scrollBarWidth  ) > windowWidth             ? windowWidth             : ( tableWidth  + scrollBarWidth ) ;
	var ourterDivHeight= ( tableHeight + scrollBarHeight ) > windowHeight - tableTop ? windowHeight - tableTop : ( tableHeight + scrollBarHeight) ;

	ourterDiv.style.width  = ourterDivWidth ;
	ourterDiv.style.height = ourterDivHeight;

	scrollBodyDivStyles += "height: " + (ourterDivHeight - sHeaderHeight) + "px;";

	// ボディのスクロール部のテーブルのスタイル
	scrollBodyTableStyles += "margin-left: " + (fixedHeaderDivWidth * -1) + "px;";
	scrollBodyTableStyles += "table-layout: fixed;";

	// ボディのスクロール部の枠のスタイル
	scrollBodyDivStyles += "margin-left: " + fixedHeaderDivWidth + "px;";
	scrollBodyDivStyles += "width: " + ( ourterDivWidth - fixedHeaderDivWidth ) + "px;";

	scrollBodyDiv.style.cssText   = scrollBodyDivStyles;
	scrollBodyTable.style.cssText = scrollBodyTableStyles;

	// スクロールのイベント処理
	scrollBodyDiv.onscroll = function () {
		// scrollHeaderDivをscrollBodyDivのスクロール（横方向）と連動させる。
		scrollHeaderDiv.style.right = scrollBodyDiv.scrollLeft + "px";
		// fixBodyDivをscrollBodyDivのスクロール（縦方向）と連動させる。
		fixBodyDiv.style.top = (scrollBodyDiv.scrollTop * -1) + "px";
	};
	return true;
};

// メイン処理（画面から呼び出す）
function adjustTable(){
	// iTable
	var iTable = document.getElementsByTagName( "iTable" );
	// iTableが存在しなければ終了
	if( iTable == null || iTable.length == 0 ){ return false; }
	// 
	fixedCols = parseInt( iTable[0].fixedCols || "0" );
	
	// 二分割の処理を行う。
	makeSuperTable( "viewTable" ,fixedCols );
};

// 実際に呼び出す場合は引数でコントロールする
return function(_mode){
	if(_mode == 'adjustTable'){
		adjustTable();
	}
	else if(_mode == 'adjustGant'){
		adjustGant();
	}
};
})();

// クロージャー外からのCall用
function adjustTable(){
	adjustGantTable('adjustTable');
};

function adjustGant(){
	adjustGantTable('adjustGant');
};
