﻿

   // function that loads each Task Item and fills TaskList array with each task attributes.

   // You should be able to add items to the chart in realtime via javascript and issuing "g.Draw()" command.

   // Parameters:

   // pID: (required) is a unique ID used to identify each row for parent functions and for setting dom id for hiding/showing

   // pName: (required) is the task Label

   // pStart: (required) the task start date, can enter empty date ('') for groups

   // pEnd: (required) the task end date, can enter empty date ('') for groups

   // pColor: (required) the html color for this task; e.g. '00ff00'

   // pLink: (optional) any http link navigated to when task bar is clicked.

   // pMile: UNUSED - in future will represent a milestone

   // pRes: (optional) resource name

   // pComp: (required) completion percent

   // pGroup: (optional) indicates whether this is a group(parent) - 0=NOT Parent; 1=IS Parent

   // pParent: (required) identifies a parent pID, this causes this task to be a child of identified task

   // pOpen: UNUSED - in future can be initially set to close folder when chart is first drawn

/* Open New Window */
function FunWinOpen(url)
{
    var win_name = 'f1'
    if(this.name=='f1')
            win_name = 'f2';

	var f1=window.open(url,win_name);
	f1.focus();
	f1.location.reload(true);

}


var JSGantt; if (!JSGantt) JSGantt = {};

//function JSGantt() {}

JSGantt.isIE = function () {
	
	if(typeof document.all != 'undefined')
	return true;
	else
	return false;
	}

function Graphics(canvas)
{

	this.canvas = canvas;

	this.cache = new Array;

	this.shapes = new Object;

	this.nObject = 0;

	// defaults

	this.penColor = "black";

	this.zIndex = 0;

}


Graphics.prototype.createPlotElement = function(x,y,w,h) {

		if ( (this.canvas == undefined) || (this.canvas == "") ) 
			this.oCanvas = document.body;
		else 
			this.oCanvas = document.getElementById(this.canvas);

	// retrieve DIV
	var oDiv;
	
		oDiv = document.createElement('div');
		this.oCanvas.appendChild(oDiv);

		oDiv.style.position = "absolute";
		oDiv.style.margin = "0px";
		oDiv.style.padding = "0px";
		oDiv.style.overflow = "hidden";
		oDiv.style.border = "0px";

	// set attributes
	oDiv.style.zIndex = this.zIndex;
	oDiv.style.backgroundColor = this.penColor;
	
	oDiv.style.left = x;
	oDiv.style.top = y;
	oDiv.style.width = w + "px";
	oDiv.style.height = h + "px";

	oDiv.style.visibility = "visible";
	
	return oDiv;
}


Graphics.prototype.releasePlotElement = function(oDiv)

{

	oDiv.style.visibility = "hidden";

	this.cache.push(oDiv);

}



Graphics.prototype.addShape = function(shape)

{

	shape.oGraphics = this;

	shape.graphicsID = this.nObject;

	this.shapes[this.nObject] = shape;

	this.nObject++;

	shape.draw();

	return shape;

}



Graphics.prototype.removeShape = function(shape)

{

	if ( (shape instanceof Object) && 

		(shape.oGraphics == this) && 

		(this.shapes[shape.graphicsID] == shape) )

	{

		shape.undraw();

		this.shapes[shape.graphicsID] = undefined;

		shape.oGraphics = undefined;

	}

}

Graphics.prototype.clear = function()

{

	for ( var i in this.shapes )

		this.removeShape(this.shapes[i]);

}





//=============================================================================

// Point

Graphics.prototype.drawPoint = function(x,y)

{

	return this.addShape(new Point(x,y))

}



function Point(x,y)

{

	this.x = x;

	this.y = y;

}

Point.prototype.draw = function()

{

	this.oDiv = this.oGraphics.createPlotElement(this.x,this.y,1,1);

}

Point.prototype.undraw = function()

{

	this.oGraphics.releasePlotElement(this.oDiv);

	this.oDiv = undefined;

}



//=============================================================================

// Line

Graphics.prototype.drawLine = function(x1,y1,x2,y2)
{

	return this.addShape(new Line(x1,y1,x2,y2))

}



function Line(x1,y1,x2,y2)
{

	this.x1 = x1;

	this.y1 = y1;

	this.x2 = x2;

	this.y2 = y2;

}



Line.prototype.draw = function()
{

	this.plots = new Array;

	var dx = this.x2 - this.x1;

	var dy = this.y2 - this.y1;

	var x = this.x1;

	var y = this.y1;

	var n = Math.max(Math.abs(dx),Math.abs(dy));

	dx = dx / n;

	dy = dy / n;

	for ( i = 0; i <= n; i++ )

	{

		this.plots.push(this.oGraphics.createPlotElement(Math.round(x),Math.round(y),1,1));



		x += dx;

		y += dy;

	}

}

Line.prototype.undraw = function()
{

	while ( this.plots.length )

		this.oGraphics.releasePlotElement(this.plots.pop());

	this.plots = undefined;

}

JSGantt.TaskItem = function(pID, pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCheckPoint,pFoldNno , pWBSID, pTaskItemColor)
   {

      var vID    = pID;

      var vName  = pName;

      var vStart = new Date();	

      var vEnd   = new Date();

      var vColor = pColor;

      var vLink  = pLink;

      var vMile  = pMile;

      var vRes   = pRes;

      var vComp  = pComp;

      var vGroup = pGroup;

      var vParent = pParent;

      var vOpen   = pOpen;

      var vDepend = pDepend;

      var vLevel = 0;

      var vNumKid = 0;

      var vShow  = 1;
      
      //查核點資料
      var vCheckPoint = pCheckPoint;
      
      //工作項目對應目錄
      var vFoldNno = pFoldNno;
      
      //工作項目ID
      var vWBSID = pWBSID;
      
      //工作列所顯示顏色
      var vTaskItemColor = pTaskItemColor;
    
      var x1, y1, x2, y2;

      if (vGroup != 1)
      {  

         var vDateParts = pStart.split('/');

         vStart.setFullYear(parseInt(vDateParts[0], 10), parseInt(vDateParts[1], 10) - 1, parseInt(vDateParts[2], 10));

         vDateParts = pEnd.split('/'); 

         vEnd.setFullYear(parseInt(vDateParts[0], 10), parseInt(vDateParts[1], 10) - 1, parseInt(vDateParts[2], 10));		

      }



      this.getID       = function(){ return vID };

      this.getName     = function(){ return vName };

      this.getStart    = function(){ return vStart};

      this.getEnd      = function(){ return vEnd  };

      this.getColor    = function(){ return vColor};

      this.getLink     = function(){ return vLink };

      this.getMile     = function(){ return vMile };

	  this.getDepend     = function(){ return vDepend };

      this.getResource = function(){ if(vRes) return vRes; else return '&nbsp';  };

      this.getCompVal  = function(){ if(vComp) return vComp; else return 0; };

      this.getCompStr  = function(){ if(vComp) return vComp+'%'; else return ''; };
   
      this.getCheckPoint = function(){
	                                    return vCheckPoint;
	                                }
	 
	  this.getFoldNno     = function(){ return vFoldNno };
	                                
	  this.getWBSID    = function(){ return vWBSID };
	  
	  this.getTaskItemColor     = function(){ return vTaskItemColor };
	                         
      this.getDuration = function(vFormat){ 

        if (vMile) return '-';

		if(vFormat == 'day') {

          tmpDays =  Math.ceil((this.getEnd() - this.getStart()) /  (24 * 60 * 60 * 1000) + 1);
               if(isNaN(tmpDays)) tmpDays = 0;
               if(tmpDays == 1) return (tmpDays + ' Day'); else return(tmpDays + ' Days'); 

        }

        if(vFormat == 'week') {

          tmpWeeks =  ((this.getEnd() - this.getStart()) /  (24 * 60 * 60 * 1000) + 1)/7;
                if(isNaN(tmpWeeks)) tmpWeeks = 0;
               if(tmpWeeks == 1) return ('1 Week'); else return(tmpWeeks.toFixed(1) + ' Weeks'); 

        }

        if(vFormat == 'month') {

          tmpMonths =  ((this.getEnd() - this.getStart()) /  (24 * 60 * 60 * 1000) + 1)/30;
                if(isNaN(tmpMonths)) tmpMonths = 0;
               if(tmpMonths == 1) return ('1 Month'); else return(tmpMonths.toFixed(1) + ' Months'); 
        }

      };

      this.getParent   = function(){ return vParent };

      this.getGroup    = function(){ return vGroup };

      this.getOpen     = function(){ return vOpen };

      this.getLevel    = function(){ return vLevel };

      this.getNumKids  = function(){ return vNumKid };

      this.getStartX   = function(){ return x1 };

      this.getStartY   = function(){ return y1 };

      this.getEndX     = function(){ return x2 };

      this.getEndY     = function(){ return y2 };

	  this.setDepend   = function(pDepend){ vDepend = pDepend;};

      this.setStart    = function(pStart){ vStart = pStart;};

      this.setEnd      = function(pEnd)  { vEnd   = pEnd;  };

      this.setLevel    = function(pLevel){ vLevel = pLevel;};

      this.setNumKid   = function(pNumKid){ vNumKid = pNumKid;};

      this.setCompVal  = function(pCompVal){ vComp = pCompVal;};

      this.setStartX   = function(pX) {x1 = pX; };

      this.setStartY   = function(pY) {y1 = pY; };

      this.setEndX     = function(pX) {x2 = pX; };

      this.setEndY     = function(pY) {y2 = pY; };
  }
	
  // function that loads the main gantt chart properties and functions

  // pDiv: (required) this is a DIV object created in HTML

  // pStart: UNUSED - future use to force minimum chart date

  // pEnd: UNUSED - future use to force maximum chart date

  // pWidth: UNUSED - future use to force chart width and cause objects to scale to fit within that width

  // pShowRes: UNUSED - future use to turn on/off display of resource names

  // pShowDur: UNUSED - future use to turn on/off display of task durations

  // pFormat: (required) - used to indicate whether chart should be drawn in "day", "week", or "month" format

JSGantt.GanttChart =  function(pGanttVar, pDiv, pStart, pEnd, pWidth, pShowRes, pShowDur, pFormat)

  {

	  var vGanttVar = pGanttVar;
	  
      var vDiv      = pDiv;

      var vStart    = new Date();	

      var vEnd      = new Date();

      var vColWidth    = pWidth;

      var vShowres  = pShowRes;

      var vShowDur  = pShowDur;

      var vFormat   = pFormat;
      var vFormat   = 'month';

      var vNumUnits  = 0;

	  var gr = new Graphics('rightside');

      var vTaskList = new Array();		

      var month=new Array(12);

          month[0]="January";

          month[1]="February";

          month[2]="March";

          month[3]="April";

          month[4]="May";

          month[5]="June";

          month[6]="July";

          month[7]="August";

          month[8]="September";

          month[9]="October";

          month[10]="November";

          month[11]="December";

	this.CalcTaskXY = function () 

  {

        var vList = this.getList();

		var vTaskDiv;

        var vParDiv;

        var vLeft, vTop, vHeight, vWidth;

        for(i = 0; i < vList.length; i++)

        {

          vID = vList[i].getID();

          vTaskDiv = document.getElementById("taskbar_"+vID);

          vBarDiv  = document.getElementById("bardiv_"+vID);

          vParDiv  = document.getElementById("childgrid_"+vID);

          if(vBarDiv) {

            vList[i].setStartX( vBarDiv.offsetLeft );

            vList[i].setStartY( vParDiv.offsetTop+vBarDiv.offsetTop+6 );

            vList[i].setEndX( vBarDiv.offsetLeft + vBarDiv.offsetWidth );

            vList[i].setEndY( vParDiv.offsetTop+vBarDiv.offsetTop+6 );

          }

        }
        
  }

    this.AddTaskItem = function(value)

    {

         vTaskList.push(value);
    }

    this.getList   = function() { return vTaskList };

    this.setFormat = function(pFormat){ vFormat = pFormat; this.Draw(); };

	this.getGraphics = function() {return gr;};

	this.drawDependency =function(x1,y1,x2,y2)
	{

	var gr = this.getGraphics();

	 gr.penColor = "red";

	if(x1 < x2)

	{

	 gr.drawLine(x1,y1,x1+5,y1);

	 gr.drawLine(x1+5,y1,x1+5,y2);

	 gr.drawLine(x1+5,y2,x2,y2);

	}

	else

	{

	var Xpoints = new Array(x1,x1+5,   x1+5,   x2-5,    x2-5,x2);

	var Ypoints = new Array(y1,y1,   y2-5,    y2-5,    y2,y2);

	 gr.drawLine(x1,y1,x1+5,y1);

	 gr.drawLine(x1+5,y1,x1+5,y2-10);

	 gr.drawLine(x1+5,y2-10,x2-5,y2-10);

	 gr.drawLine(x2-5,y2-10,x2-5,y2);

	 gr.drawLine(x2-5,y2,x2,y2);

	}

	}

	this.DrawDependencies = function (){

		//First recalculate the x,y

		this.CalcTaskXY();

		var gr = this.getGraphics();

		gr.clear();

	  	var vList = this.getList();

        for(var i = 0; i < vList.length; i++)
        {

		    if(!isNaN(vList[i].getDepend()) && document.getElementById("childgrid_"+vList[i].getID()).style.display=='')

		    {

		        var ii = this.getArrayLocationByID(vList[i].getDepend())

			    if(document.getElementById("childgrid_"+vList[ii].getID()).style.display=='')

			    {

			     this.drawDependency(vList[ii].getEndX(),vList[ii].getEndY(),vList[i].getStartX(),vList[i].getStartY())

			    }

		    }

		}

	}

	this.getArrayLocationByID = function(pId)  {

	 var vList = this.getList();

	 for(var i = 0; i < vList.length; i++)

	 {

	     if(vList[i].getID()==pId)
	                    return i;

	 }

	}
	

    this.Draw = function()

    {

         var vCurrDate = new Date();

         var vMaxDate = new Date();

         var vMinDate = new Date();	

         var vTmpDate = new Date();

         var vNxtDate = new Date();

         var vTaskLeft = 0;

         var vTaskRight = 0;

         var vNumCols = 0;

         var vID = 0;

         var vMainTable = new Array();

         var vLeftTable = new Array();

         var vRightTable = new Array();

         var vDateRowStr = new Array();

         var vItemRowStr =  new Array();
         var vItemRowStr_2 =  new Array();

         var vSpanSet = 0;

         var vColWidth = 0;

         var vColUnit = 0;

         var vChartWidth = 0;

         var vNumDays = 0;

         var vDayWidth = 0;

         var vStr = "";

      if(vTaskList.length > 0)
      {

        vCurrDate.setFullYear(vCurrDate.getFullYear(), vCurrDate.getMonth(), vCurrDate.getDate());

        // Process all tasks preset parent date and completion %

        JSGantt.processRows(vTaskList, 0, -1, 1);

        // get overall min/max dates plus padding

        vMinDate = JSGantt.getMinDate(vTaskList, vFormat);

        vMaxDate = JSGantt.getMaxDate(vTaskList, vFormat);

        // Calculate chart width variables.  vColWidth can be altered manually to change each column width

        // May be smart to make this a parameter of GanttChart or set it based on existing pWidth parameter

        if(vFormat == 'day') {

          vColWidth = 18;

          vColUnit = 1;

        }

        if(vFormat == 'week') {

          vColWidth = 37;

          vColUnit = 7;

        }

        if(vFormat == 'month') {

          vColWidth = 37;

          vColUnit = 30;

        }

        vNumDays = Math.ceil((Date.parse(vMaxDate) - Date.parse(vMinDate)) / ( 24 * 60 * 60 * 1000));

        vNumUnits = vNumDays / vColUnit;

        vChartWidth = vNumUnits * vColWidth + 1;

        vDayWidth = (vColWidth / vColUnit) + (1/vColUnit);
        var table_width = 270+100;

         /****************************標頭列 Start ************************/
         vLeftTable[vLeftTable.length] =
           '<TR>' +
            //工作項目欄位
           '<TD style="BORDER-TOP: #efefef 1px solid; WIDTH: 270px;">工作項目</TD>' +
           '<TD style="WIDTH:100px;">時程</TD>' +
            //日期欄位
            '<TD style="width: ' + vChartWidth+
             'px;" vAlign=top><TABLE cellSpacing=0 cellPadding=0 border=0><TR>';
              vTmpDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate());
            
        // Major Date Header
         while(Date.parse(vTmpDate) <= Date.parse(vMaxDate))
         {	
            vStr = vTmpDate.getFullYear() + '';
            //vStr = vStr.substring(2,4);
	        if(vFormat == 'day')
            {
		        vLeftTable[vLeftTable.length]= '<td class=gdatehead align=center colspan=7>' ;
		        vLeftTable[vLeftTable.length]= vTmpDate.getFullYear();
		        vLeftTable[vLeftTable.length]=  '/';
		        vLeftTable[vLeftTable.length]=(vTmpDate.getMonth()+1) ;
		        vLeftTable[vLeftTable.length]= '/' ;
		        vLeftTable[vLeftTable.length]= vTmpDate.getDate() ;
		        vLeftTable[vLeftTable.length]= ' - <br/>';

                vTmpDate.setDate(vTmpDate.getDate()+6);

		        vLeftTable[vLeftTable.length]=   vStr ;
		        vLeftTable[vLeftTable.length]= '/'  ;
		        vLeftTable[vLeftTable.length]= (vTmpDate.getMonth()+1) ;
		        vLeftTable[vLeftTable.length]= '/' ;
		        vLeftTable[vLeftTable.length]= vTmpDate.getDate() ;
		        vLeftTable[vLeftTable.length]= '</td>';

                vTmpDate.setDate(vTmpDate.getDate()+1);
           }

           if(vFormat == 'week')
           {

		        vLeftTable[vLeftTable.length]= '<td class=gdatehead align=center width=';
		        vLeftTable[vLeftTable.length]=vColWidth;
		        vLeftTable[vLeftTable.length]='>';
		        vLeftTable[vLeftTable.length]= vStr ;
		        vLeftTable[vLeftTable.length]= '</td>';

                vTmpDate.setDate(vTmpDate.getDate()+7);

           }

           if(vFormat == 'month')
           {
	             vLeftTable[vLeftTable.length]= '<td class=gdatehead align=center width=';
	             vLeftTable[vLeftTable.length]=vColWidth;
	             vLeftTable[vLeftTable.length]='>';
	             vLeftTable[vLeftTable.length]= vStr ;
	             vLeftTable[vLeftTable.length]= '</td>';

                 vTmpDate.setDate(vTmpDate.getDate() + 1);

                 while(vTmpDate.getDate() > 1)
                 {
                   vTmpDate.setDate(vTmpDate.getDate() + 1);
                 }

           }

        } 
        
        /**************** Date Table ***********************/
                vLeftTable[vLeftTable.length]= '</TR><TR>';

         // Minor Date header and Cell Rows
         vTmpDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate());

         vNxtDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate());

         vNumCols = 0;
         while(Date.parse(vTmpDate) <= Date.parse(vMaxDate))
         {
          table_width +=vColWidth+1;
	        if(vFormat == 'day')
            {
              if(vTmpDate.getDay() % 6 == 0) {

                vDateRowStr[vDateRowStr.length]= '<td><div class=wd>' + vTmpDate.getDate() + '</div></td>';
                 vItemRowStr[vItemRowStr.length] = '<td class=wd />';
              }

              else {

                vDateRowStr[vDateRowStr.length]= '<td><div class=d>' + vTmpDate.getDate() + '</div></td>';

                 vItemRowStr[vItemRowStr.length] = '<td class=d />';
              }

              vTmpDate.setDate(vTmpDate.getDate() + 1);
            }

	        if(vFormat == 'week')

            {
              vNxtDate.setDate(vNxtDate.getDate() + 7);

              if(vNxtDate <= vMaxDate) {

                vDateRowStr[vDateRowStr.length]= '<td class="ghead" style="BORDER-TOP: #efefef 1px solid;BORDER-LEFT: #efefef 1px solid;" align=middle width:'+vColWidth+'><div style="width: '+vColWidth+'">' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '</div></td>';

                vItemRowStr[vItemRowStr.length] = '<td class="ghead" style="BORDER-TOP: #efefef 1px solid;BORDER-LEFT: #efefef 1px solid;" align=middle><div style="width: ';
                vItemRowStr[vItemRowStr.length] = vColWidth;
                vItemRowStr[vItemRowStr.length] = '">&nbsp;</div></td>';

              } else {

                vDateRowStr[vDateRowStr.length]= '<td class="ghead" style="BORDER-TOP: #efefef 1px solid;BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=middle width:'+vColWidth+'><div style="width: '+vColWidth+'">' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '</div></td>';

                vItemRowStr[vItemRowStr.length] = '<td class="ghead" style="BORDER-TOP: #efefef 1px solid;BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=middle><div style="width: ';
                vItemRowStr[vItemRowStr.length] = vColWidth;
                vItemRowStr[vItemRowStr.length] = '">&nbsp;</div></td>';

              }

              vTmpDate.setDate(vTmpDate.getDate() + 7);
            }

	        if(vFormat == 'month')

            {
              vNxtDate.setDate(vNxtDate.getDate() + 31);

              if(vNxtDate <= vMaxDate) {

                vDateRowStr[vDateRowStr.length]= '<td class="ghead" style="BORDER-TOP: #efefef 1px solid;BORDER-LEFT: #efefef 1px solid;" align=middle><div style="width: '+vColWidth+'">' + month[vTmpDate.getMonth()].substr(0,3) + '</div></td>';

                vItemRowStr[vItemRowStr.length] = '<td class="ghead" style="BORDER-TOP: #efefef 1px solid;BORDER-LEFT: #efefef 1px solid;" align=middle><div style="width: '+vColWidth+'">&nbsp</div></td>';

              } else {

                vDateRowStr[vDateRowStr.length]= '<td class="ghead" style="BORDER-TOP: #efefef 1px solid;BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=middle width:'+vColWidth+'><div style="width: '+vColWidth+'">' + month[vTmpDate.getMonth()].substr(0,3) + '</div></td>';

                vItemRowStr[vItemRowStr.length] = '<td class="ghead" style="BORDER-TOP: #efefef 1px solid;BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=middle><div style="width: '+vColWidth+'">&nbsp;</div></td>';
              }

              vTmpDate.setDate(vTmpDate.getDate() + 1);

              while(vTmpDate.getDate() > 1)
              {
                
                vTmpDate.setDate(vTmpDate.getDate() + 1);
              }

            }
        }
        
        vLeftTable[vLeftTable.length]= vDateRowStr.join('');
        vLeftTable[vLeftTable.length] = '</tr></table></td></tr>';
        /*設定整各Table大小*/
       if(vFormat == 'week')
                table_width-=1;
                
       if(vFormat == 'day')
                table_width-=2;
     vMainTable[vMainTable.length] =
           '<DIV class=scroll2 id=rightside>' + 
           '<TABLE id=theTable cellSpacing=0 cellPadding=0 border=0 bgColor=#ffffff style="FONT-SIZE: 12pt;" width=' + 
           table_width + '>' ;
       /****************************標頭列 End ************************/
   
       /****************************內容列 Start **********************/
            for(i = 0; i < vTaskList.length; i++)
            {
                //項目欄位
               vID = vTaskList[i].getID();
        
               vLeftTable[vLeftTable.length]= 
                  '<TR id=child_' + vID + '>' +
                  '<TD class=gname style="BORDER-TOP: #efefef 1px solid;" >';
                  
              vLeftTable[vLeftTable.length]= 
               '<a href="javascript:FunWinOpen(\'Projects/PRJWBSITEM.aspx?WBSID=' + vTaskList[i].getWBSID()+ '\');\"  >' +
                '<span style="color:Blue">' + vTaskList[i].getName() + '</span>' + 
                '</a></TD>';
                 
              //時程欄位
              vLeftTable[vLeftTable.length]=
                '<TD class=gname style="text-align:center;border-top:#efefef 1px solid;border-left:#efefef 1px solid;" nowrap>' + vTaskList[i].getDuration(vFormat) + '</TD>';
                
              //將所有空格畫出
              vLeftTable[vLeftTable.length]='<td>';
              vLeftTable[vLeftTable.length]= '<DIV id=childgrid_' ; 
              vLeftTable[vLeftTable.length]=  vID ; 
              vLeftTable[vLeftTable.length]=  ' style="position:relative">';
              vLeftTable[vLeftTable.length]='<table border=0  cellSpacing=0 cellPadding=0 ><tr><td>'+vItemRowStr.join('')+'</td></tr></table>' ;
              
              vDateRowStr = new Array();
              
              //將甘特圖標示出來
              /********************************************/
                if(vTaskList[i].getMile()) {
                                                }
                else
                {
                       vTaskStart = vTaskList[i].getStart();

                       vTaskEnd   = vTaskList[i].getEnd();

                       vNumCols = 0;
                       // Build date string for Title
                       vStr = vTaskStart.getFullYear() + '';

                       vStr = vStr.substring(0,4);

                       vDateRowStr[vDateRowStr.length] =   vStr + '/' + (vTaskStart.getMonth()+1) + '/' + vTaskStart.getDate() ;

                       vStr = vTaskEnd.getFullYear() + '';

                       vStr = vStr.substring(0,4);

                       vDateRowStr[vDateRowStr.length]= ' - ' +  vStr + '/' + (vTaskEnd.getMonth()+1) + '/' + vTaskEnd.getDate() ;
                        if(isNaN(vTaskStart)||isNaN(vTaskEnd)) continue;
                        
                        vTaskLeft = (Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / (24 * 60 * 60 * 1000);

                        //vTaskRight = (Date.parse(vTaskList[i].getEnd()) - Date.parse(vTaskList[i].getStart())) / (24 * 60 * 60 * 1000) + 1/vColUnit;
                        vTaskRight = (Date.parse(vTaskList[i].getEnd()) - Date.parse(vTaskList[i].getStart())) / (24 * 60 * 60 * 1000);

                        // Draw Group Bar  which has outer div with inner group div and several small divs to left and right to create angled-end indicators
                        if( vTaskList[i].getGroup()) {
		                    vLeftTable[vLeftTable.length]=
                                   '<div id=bardiv_' + vID + ' style="position:absolute; vertical-align:middle; left:' + Math.ceil(vTaskLeft * (vDayWidth) + 1) + 'px; height: 7px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px">' +

                                   '<div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr.join('') + '" class=gtask style="background-color:#000000; height: 7px; width:' + Math.ceil((vTaskRight) * (vDayWidth) -1) + 'px;  cursor: pointer;">' +

                                   '<div style="Z-INDEX: -4; float:left; background-color:#666666; height:3px; overflow: hidden; margin-top:1px; ' +

                                      'margin-left:1px; margin-right:1px; filter: alpha(opacity=80); opacity:0.8; width:' + vTaskList[i].getCompStr() + '; ' + 

                                      'cursor: pointer;" onclick=JSGantt.taskLink("' + vTaskList[i].getLink() + '");></div></div>' +

                                    '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:1px; overflow: hidden; width:1px;"></div>' +

                                    '</div>' ;
                            vDateRowStr=new Array();


                        } else {

                            // Draw Task Bar  which has outer DIV with enclosed colored bar div, and opaque completion div

		                    vLeftTable[vLeftTable.length]=
                                   '<div id=bardiv_' + vID + ' style="position:absolute; top:6px; left:' + Math.ceil(vTaskLeft * (vDayWidth) + 1) + 'px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px">' +
                                    '<a href="javascript:FunWinOpen(\'Projects/PRJWBSITEM.aspx?WBSID=' + vTaskList[i].getWBSID()+ '\');\"  >' +
                                   '<div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr.join('') + '" class=gtask style="background-color:' + vTaskList[i].getTaskItemColor() +'; height: 13px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px; cursor: pointer;">' ;
                                
                            vDateRowStr=new Array();
                            var TaskCKPoints = vTaskList[i].getCheckPoint().split(';');
                            for(j = 0;j<TaskCKPoints.length;j++)
                            {
                               
                                if ( TaskCKPoints[j].length > 1)
                                       {
                                              var TaskCKPointInfo = TaskCKPoints[j].split(',');
                                             
                                              var ckColor = 'red';
                                                if(TaskCKPointInfo.length >3)     
                                                    ckColor=TaskCKPointInfo[3];
                          
                                              vLeftTable[vLeftTable.length]=        
                                                        //新增查核點
                                                        '<a  href="javascript:FunWinOpen(\'Projects/PRJRPT.aspx?Chkid=' + TaskCKPointInfo[0] + '\');\"  >' +
                                                        '<div id=taskbar2'+ j +'_' + vID + ' title="' + '檢查點' + ': ' + TaskCKPointInfo[1] + '" class=gtask style="position:absolute;  left:' + Math.ceil((DateDiff(vTaskStart,TaskCKPointInfo[1])) * (vDayWidth) ) + 'px; background-color:'+ckColor+'; height: 13px; width:' + Math.ceil((vDayWidth) - 1) + 'px; cursor: pointer;" ' +
                                                          ');></div></a>';
                                        }
                            }
                            //新增系統日期 -> robin
                            //vLeftTable[vLeftTable.length]= '<div id=today2_' + vID + ' title="Today" class=gtask style="position:absolute;  left:' + Math.ceil((DateDiff(vTaskStart,'2009/04/17')) * (vDayWidth) ) + 'px; background-color:black; height: 13px; width:' + Math.ceil((vDayWidth) - 1) + 'px;"></div>';
                     
                            vLeftTable[vLeftTable.length]=        
                                    '<div class=gcomplete style="Z-INDEX: -4; float:left; background-color:black; height:5px; overflow: auto; margin-top:4px; filter: alpha(opacity=40); opacity:0.4; width:' + vTaskList[i].getCompStr() + '; overflow:hidden"></div></div></a></div>' ;

                        }
                }
                vLeftTable[vLeftTable.length]='</div>';
              vLeftTable[vLeftTable.length]='</td>';
                 
              /********************************************/
              vLeftTable[vLeftTable.length]= '</TR>';
            }
            
              /******************切換選單******************/
              vLeftTable[vLeftTable.length] = "</td></tr></table></div>";
              vLeftTable[vLeftTable.length] = "<div>";
                if (vFormat=='day') vLeftTable[vLeftTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" VALUE="day" checked>Day';

            else                vLeftTable[vLeftTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("day",'+vGanttVar+'); VALUE="day">Day';



            if (vFormat=='week') vLeftTable[vLeftTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" VALUE="week" checked>Week';

            else                vLeftTable[vLeftTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("week",'+vGanttVar+') VALUE="week">Week';



            if (vFormat=='month') vLeftTable[vLeftTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" checked>Month';

            else                vLeftTable[vLeftTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("month",'+vGanttVar+') VALUE="month">Month';

            // DRAW the date format selector at bottom left.  Another potential GanttChart parameter to hide/show this selector
            vLeftTable[vLeftTable.length]='</div>';
            vDiv.innerHTML =vMainTable.join('') + vLeftTable.join('');
            return;
    /************ 切換選單 END ****************************************************/
         // Minor Date header and Cell Rows

         vTmpDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate());

         vNxtDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate());

         vNumCols = 0;
         while(Date.parse(vTmpDate) <= Date.parse(vMaxDate))
         {	

	    if(vFormat == 'day')
            {
              if(vTmpDate.getDay() % 6 == 0) {

                vDateRowStr[vDateRowStr.length]= '<td><div class=wd>' + vTmpDate.getDate() + '</div></td>';
                 vItemRowStr[vItemRowStr.length] = '<td><div class=wd /></td>';
                 //vItemRowStr[vItemRowStr.length] = '<td class=wd width=200>d</td>';
              }

              else {

                vDateRowStr[vDateRowStr.length]= '<td><div class=d>' + vTmpDate.getDate() + '</div></td>';

                 vItemRowStr[vItemRowStr.length] = '<td><div class=d /></td>';
                 //vItemRowStr[vItemRowStr.length] = '<div class=d />';

              }


              vTmpDate.setDate(vTmpDate.getDate() + 1);


            }



	    if(vFormat == 'week')

            {



              vNxtDate.setDate(vNxtDate.getDate() + 7);

              if(vNxtDate <= vMaxDate) {

                vDateRowStr[vDateRowStr.length]= '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12pt; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" align=middle width:'+vColWidth+'><div style="width: '+vColWidth+'">' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '</div></td>';

                vItemRowStr[vItemRowStr.length] = '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12pt; BORDER-LEFT: #efefef 1px solid;" align=middle><div style="width: ';
                vItemRowStr[vItemRowStr.length] = vColWidth;
                vItemRowStr[vItemRowStr.length] = '">&nbsp&nbsp</div></td>';

              } else {

                vDateRowStr[vDateRowStr.length]= '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12pt; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=middle width:'+vColWidth+'><div style="width: '+vColWidth+'">' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '</div></td>';

                vItemRowStr[vItemRowStr.length] = '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12pt; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=middle><div style="width: ';
                vItemRowStr[vItemRowStr.length] = vColWidth;
                vItemRowStr[vItemRowStr.length] = '">&nbsp&nbsp</div></td>';

              }


              vTmpDate.setDate(vTmpDate.getDate() + 7);


            }



	    if(vFormat == 'month')

            {

              vNxtDate.setDate(vNxtDate.getDate() + 31);

              if(vNxtDate <= vMaxDate) {

                vDateRowStr[vDateRowStr.length]= '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12pt; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" align=middle width:'+vColWidth+'><div style="width: '+vColWidth+'">' + month[vTmpDate.getMonth()].substr(0,3) + '</div></td>';

                vItemRowStr[vItemRowStr.length] = '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12pt; BORDER-LEFT: #efefef 1px solid;" align=middle><div style="width: '+vColWidth+'">&nbsp&nbsp</div></td>';

              } else {

                vDateRowStr[vDateRowStr.length]= '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12pt; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=middle width:'+vColWidth+'><div style="width: '+vColWidth+'">' + month[vTmpDate.getMonth()].substr(0,3) + '</div></td>';

                vItemRowStr[vItemRowStr.length] = '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12pt; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=middle><div style="width: '+vColWidth+'">&nbsp&nbsp</div></td>';

              }

              vTmpDate.setDate(vTmpDate.getDate() + 1);

              while(vTmpDate.getDate() > 1)

              {

                vTmpDate.setDate(vTmpDate.getDate() + 1);

              }



            }



        }


        vRightTable[vRightTable.length]= vDateRowStr.join('');
        vDateRowStr=new Array();
        
        vRightTable[vRightTable.length]= '</TR>';

        vRightTable[vRightTable.length]= '</TBODY></TABLE>';
        // Draw each row
        for(i = 0; i < vTaskList.length; i++)

        {
    
           vTmpDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate());

           vTaskStart = vTaskList[i].getStart();

           vTaskEnd   = vTaskList[i].getEnd();

           vNumCols = 0;

           vID = vTaskList[i].getID();

           vNumUnits = Math.ceil((vTaskList[i].getEnd() - vTaskList[i].getStart()) / (24 * 60 * 60 * 1000)) + 1;

           vSpanSet = 0;
            /*********************問題點*****************/
           vRightTable[vRightTable.length]= '<DIV id=childgrid_' ; 
           vRightTable[vRightTable.length]=  vID ; 
           //vRightTable[vRightTable.length]=  ' class=yesdisplay style="position:relative">';
            vRightTable[vRightTable.length]=  ' style="position:relative">';

           vRightTable[vRightTable.length]= '<DIV><TABLE style="position:relative; width: ';
           vRightTable[vRightTable.length]=  vChartWidth
           //vRightTable[vRightTable.length]=  'px;" cellSpacing=0 cellPadding=0 border=0><TR class=yesdisplay style="HEIGHT: 20px">';
           vRightTable[vRightTable.length]=  'px;" cellSpacing=0 cellPadding=0 border=0><TR>';
           vRightTable[vRightTable.length]=  vItemRowStr.join('') ;
           vRightTable[vRightTable.length]=  '</TR></TABLE></DIV>';
            /***********************************************/

             if( vTaskList[i].getMile()) {

                   // Build date string for Title

                   vStr = vTaskStart.getFullYear() + '';

                   vStr = vStr.substring(2,4);

                   vDateRowStr[vDateRowStr.length] = vTaskStart.getMonth() + '/' + vTaskStart.getDate() + '/' + vStr;

                   vTaskLeft = (Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / (24 * 60 * 60 * 1000);

                   vTaskRight = 1

		            vRightTable[vRightTable.length]=

                               '<div id=bardiv_' + vID + ' style="position:absolute; top:0px; left:' + Math.ceil((vTaskLeft * (vDayWidth) + 1)) + 'px; height: 16px; width:12px; overflow:hidden;">' +

                               '<div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr.join('') + '" style="height: 16px; width:12px; overflow:hidden; cursor: pointer;" onclick=JSGantt.taskLink("' + vTaskList[i].getLink() + '");>';

                    vDateRowStr=new Array();

                    if(vTaskList[i].getCompVal() < 100)
 		                    vRightTable[vRightTable.length]= '&loz;</div></div>' ;
                    else
                            vRightTable[vRightTable.length]= '&diams;</div></div>' ;
             } else {

                       // Build date string for Title

                       vStr = vTaskStart.getFullYear() + '';

                       vStr = vStr.substring(0,4);

                       vDateRowStr[vDateRowStr.length] =   vStr + '/' + (vTaskStart.getMonth()+1) + '/' + vTaskStart.getDate() ;

                       vStr = vTaskEnd.getFullYear() + '';

                       vStr = vStr.substring(0,4);

                       vDateRowStr[vDateRowStr.length]= ' - ' +  vStr + '/' + (vTaskEnd.getMonth()+1) + '/' + vTaskEnd.getDate() ;
                        if(isNaN(vTaskStart)||isNaN(vTaskEnd)) continue;
                        vTaskLeft = (Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / (24 * 60 * 60 * 1000);

                        vTaskRight = (Date.parse(vTaskList[i].getEnd()) - Date.parse(vTaskList[i].getStart())) / (24 * 60 * 60 * 1000) + 1/vColUnit;

                        // Draw Group Bar  which has outer div with inner group div and several small divs to left and right to create angled-end indicators

                        if( vTaskList[i].getGroup()) {

		                    vRightTable[vRightTable.length]=
                                   '<div id=bardiv_' + vID + ' style="position:absolute; top:5px; left:' + Math.ceil(vTaskLeft * (vDayWidth) + 1) + 'px; height: 7px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px">' +

                                   '<div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr.join('') + '" class=gtask style="background-color:#000000; height: 7px; width:' + Math.ceil((vTaskRight) * (vDayWidth) -1) + 'px;  cursor: pointer;">' +

                                   '<div style="Z-INDEX: -4; float:left; background-color:#666666; height:3px; overflow: hidden; margin-top:1px; ' +

                                      'margin-left:1px; margin-right:1px; filter: alpha(opacity=80); opacity:0.8; width:' + vTaskList[i].getCompStr() + '; ' + 

                                      'cursor: pointer;" onclick=JSGantt.taskLink("' + vTaskList[i].getLink() + '");></div></div>' +

                                    '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:1px; overflow: hidden; width:1px;"></div>' +

                                    '</div>' ;
                            vDateRowStr=new Array();


                        } else {

                            // Draw Task Bar  which has outer DIV with enclosed colored bar div, and opaque completion div

		                    vRightTable[vRightTable.length]=
                                   '<div id=bardiv_' + vID + ' style="position:absolute; top:4px; left:' + Math.ceil(vTaskLeft * (vDayWidth) + 1) + 'px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px">' +

                                   '<div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr.join('') + '" class=gtask style="background-color:' + vTaskList[i].getColor() +'; height: 13px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px; cursor: pointer;" ' +

                                     'onclick=JSGantt.taskLink("' + vTaskList[i].getLink() + '");>' ;
                            vDateRowStr=new Array();
                            var TaskCKPoints = vTaskList[i].getCheckPoint().split(';');
                            for(j = 0;j<TaskCKPoints.length;j++)
                            {
                               
                                if ( TaskCKPoints[j].length > 1)
                                       {
                                              var TaskCKPointInfo = TaskCKPoints[j].split(',');
                                             
                                              var ckColor = 'red';
                                                if(TaskCKPointInfo.length >3)     
                                                    ckColor=TaskCKPointInfo[3];
                          
                                              vRightTable[vRightTable.length]=        
                                                        //新增查核點
                                                        '<a  href="javascript:FunWinOpen(\'Projects/PRJRPT.aspx?Chkid=' + TaskCKPointInfo[0] + '\');\"  >' +
                                                        '<div id=taskbar2'+ j +'_' + vID + ' title="' + '檢查點' + ': ' + TaskCKPointInfo[1] + '" class=gtask style="position:absolute;  left:' + Math.ceil((DateDiff(vTaskStart,TaskCKPointInfo[1])) * (vDayWidth) ) + 'px; background-color:'+ckColor+'; height: 13px; width:' + Math.ceil((vDayWidth) - 1) + 'px; cursor: pointer;" ' +

                                                          ');></div></a>';
                                        }
                            }
                     
                            vRightTable[vRightTable.length]=        
                                    '<div class=gcomplete style="Z-INDEX: -4; float:left; background-color:black; height:5px; overflow: auto; margin-top:4px; filter: alpha(opacity=40); opacity:0.4; width:' + vTaskList[i].getCompStr() + '; overflow:hidden"></div></div></div>' ;

                        }

             }

          vRightTable[vRightTable.length]= '</DIV>';

        }



        vMainTable[vMainTable.length]= vRightTable.join('') + '</TD></TR></TBODY></TABLE></DIV>';
                if (vFormat=='day') vMainTable[vMainTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" VALUE="day" checked>Day';

            else                vMainTable[vMainTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("day",'+vGanttVar+'); VALUE="day">Day';



            if (vFormat=='week') vMainTable[vMainTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" VALUE="week" checked>Week';

            else                vMainTable[vMainTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("week",'+vGanttVar+') VALUE="week">Week';



            if (vFormat=='month') vMainTable[vMainTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" checked>Month';

            else                vMainTable[vMainTable.length]= '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("month",'+vGanttVar+') VALUE="month">Month';
            //alert(vMainTable.join('').length);
            //alert(vRightTable.join('').length);
            //alert(vItemRowStr.join('').length);
            
            vDiv.innerHTML = vMainTable.join('');
           //document.write( vMainTable.join(''));
         }

      }



   }		

	
  //計算天數的函數
   function  DateDiff(beginDate,  endDate){    //beginDate和endDate都是2007-8-10格式
   
       var  arrbeginDate,  Date1,  Date2, arrendDate,  iDays;  
       Date1=  new  Date(beginDate);    //轉換為2007-8-10格式
     
       
      arrendDate=  endDate.split("/") ; 
       Date2=  new  Date(arrendDate[1]  +  '-'  +  arrendDate[2]  +  '-'  +  arrendDate[0])  
       iDays  =  parseInt(Math.ceil((Date2.getTime()-Date1.getTime())/  1000  /  60  /  60  /24));    //轉換為天數 
       return  iDays;  
   }    




      // Recursively process task tree ... set min, max dates of parent tasks and identfy task level.

JSGantt.processRows = function(pList, pID, pRow, pLevel)

      {



         var vMinDate = new Date();

         var vMaxDate = new Date();

         var vMinSet  = 0;

         var vMaxSet  = 0;

         var vList    = pList;

         var vLevel   = pLevel;

         var i        = 0;

         var vNumKid  = 0;

         var vCompSum = 0;

 

         for(i = 0; i < pList.length; i++)

         {



            if(pList[i].getParent() == pID) {



               pList[i].setLevel(vLevel);

               vNumKid++;



               if(pList[i].getGroup() == 1) {

                  JSGantt.processRows(vList, pList[i].getID(), i, vLevel+1);

               }



               if( vMinSet==0 || pList[i].getStart() < vMinDate) {

                  vMinDate = pList[i].getStart();

                  vMinSet = 1;

               }



               if( vMaxSet==0 || pList[i].getEnd() > vMaxDate) {

                  vMaxDate = pList[i].getEnd();

                  vMaxSet = 1;

               }



               vCompSum += pList[i].getCompVal();



            }

				

         }



         if(pRow >= 0) {

            pList[pRow].setStart(vMinDate);

            pList[pRow].setEnd(vMaxDate);

            pList[pRow].setNumKid(vNumKid);

            pList[pRow].setCompVal(Math.ceil(vCompSum/vNumKid));

         }



      }







      // Used to determine the minimum date of all tasks and set lower bound based on format

JSGantt.getMinDate = function getMinDate(pList, pFormat)  

      {

         var vDate = new Date();

         vDate.setFullYear(pList[0].getStart().getFullYear(), pList[0].getStart().getMonth(), pList[0].getStart().getDate());



         // Parse all Task End dates to find min

         for(i = 0; i < pList.length; i++)

         {

            if(Date.parse(pList[i].getStart()) < Date.parse(vDate))

               vDate.setFullYear(pList[i].getStart().getFullYear(), pList[i].getStart().getMonth(), pList[i].getStart().getDate());

         }





         // Adjust min date to specific format boundaries (first of week or first of month)

         if (pFormat=='day')

         {

            vDate.setDate(vDate.getDate() - 4);

            while(vDate.getDay() % 6 > 0)

            {

                vDate.setDate(vDate.getDate() - 1);

            }

         }



         if (pFormat=='week')

         {

            vDate.setDate(vDate.getDate() - 7);

            while(vDate.getDay() % 6 > 0)

            {

                vDate.setDate(vDate.getDate() - 1);

            }

         }



         if (pFormat=='month')

         {

            while(vDate.getDate() > 1)

            {

                vDate.setDate(vDate.getDate() - 1);

            }

         }



         return(vDate);

      }







      // Used to determine the minimum date of all tasks and set lower bound based on format

JSGantt.getMaxDate= function (pList, pFormat)

      {

         var vDate = new Date();

         vDate.setFullYear(pList[0].getEnd().getFullYear(), pList[0].getEnd().getMonth(), pList[0].getEnd().getDate());



         // Parse all Task End dates to find max

         for(i = 0; i < pList.length; i++)

         {

            if(Date.parse(pList[i].getEnd()) > Date.parse(vDate))

            vDate.setFullYear(pList[i].getEnd().getFullYear(), pList[i].getEnd().getMonth(), pList[i].getEnd().getDate());						

         }

				

         // Adjust max date to specific format boundaries (end of week or end of month)

         if (pFormat=='day')

         {

            vDate.setDate(vDate.getDate() + 1);

            while(vDate.getDay() % 5 > 0)

            {

                vDate.setDate(vDate.getDate() + 1);

            }

         }



         if (pFormat=='week')

         {

            //For weeks, what is the last logical boundary?

            vDate.setDate(vDate.getDate() + 11);

            while(vDate.getDay() % 6 > 0)

            {

                vDate.setDate(vDate.getDate() + 1);

            }

         }



         // Set to last day of current Month

         if (pFormat=='month')

         {

            while(vDate.getDay() > 1)

            {

                vDate.setDate(vDate.getDate() + 1);

            }

            vDate.setDate(vDate.getDate() - 1);

         }



         return(vDate);

      }







      // This function finds the document id of the specified object

JSGantt.findObj = function (theObj, theDoc)

      {

         var p, i, foundObj;

         if(!theDoc) theDoc = document;

         if( (p = theObj.indexOf("?")) > 0 && parent.frames.length){

            theDoc = parent.frames[theObj.substring(p+1)].document;

            theObj = theObj.substring(0,p);

         }

         if(!(foundObj = theDoc[theObj]) && theDoc.all) 

            foundObj = theDoc.all[theObj];



         for (i=0; !foundObj && i < theDoc.forms.length; i++) 

            foundObj = theDoc.forms[i][theObj];



         for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++)

            foundObj = JSGantt.findObj(theObj,theDoc.layers[i].document);



         if(!foundObj && document.getElementById)

            foundObj = document.getElementById(theObj);



         return foundObj;

      }





JSGantt.changeFormat =      function(pFormat,ganttObj) {



        if(ganttObj) 

		{

		ganttObj.setFormat(pFormat);

		ganttObj.DrawDependencies();

		}

        else alert('Chart undefined');



      }







      // Function to open/close and hide/show children of specified task

 JSGantt.folder= function (pID,ganttObj) {


        var vList = ganttObj.getList();

        

        for(i = 0; i < vList.length; i++)

        {



          if(vList[i].getID() == pID) {



            if (JSGantt.isIE()) { // IE;



              if( JSGantt.findObj('group_'+pID).innerText == ' v') {

                JSGantt.hide(pID,ganttObj);

                JSGantt.findObj('group_'+pID).innerText = '>';

              } else {

                JSGantt.show(pID, 1,ganttObj);

                JSGantt.findObj('group_'+pID).innerText = ' v';

              }



            } else {



              if( JSGantt.findObj('group_'+pID).textContent == 'v') {

                JSGantt.hide(pID,ganttObj);

                JSGantt.findObj('group_'+pID).textContent = '>';

              } else {

                JSGantt.show(pID, 1,ganttObj);

                JSGantt.findObj('group_'+pID).textContent = 'v';

              }

            }

  

          }

        }

		

      }

  JSGantt.hide=     function (pID,ganttObj) {

         

        var vList = ganttObj.getList();

        var vID   = 0;



        for(i = 0; i < vList.length; i++)

        {



          if(vList[i].getParent() == pID) {



            vID = vList[i].getID();



            JSGantt.findObj('child_' + vID).style.display = "none";

            JSGantt.findObj('childgrid_' + vID).style.display = "none";



            if(vList[i].getGroup() == 1) 

              JSGantt.hide(vID,ganttObj);



          }

        }

      }





      // Function to show children of specified task

     JSGantt.show =  function (pID, pTop,ganttObj) {

        var vList = ganttObj.getList();

        var vID   = 0;

        for(i = 0; i < vList.length; i++)

        {

          if(vList[i].getParent() == pID) {

            vID = vList[i].getID();

            if(pTop == 1) {

              if (JSGantt.isIE()) { // IE;

                if( JSGantt.findObj('group_'+pID).innerText == '>') {

                  JSGantt.findObj('child_'+vID).style.display = "";

                  JSGantt.findObj('childgrid_'+vID).style.display = "";

                }



              } else {



                if( JSGantt.findObj('group_'+pID).textContent == '>') {

                  JSGantt.findObj('child_'+vID).style.display = "";

                  JSGantt.findObj('childgrid_'+vID).style.display = "";

                }

              }

            } else {

              if (JSGantt.isIE()) { // IE;



                if( JSGantt.findObj('group_'+pID).innerText == ' v') {

                  JSGantt.findObj('child_'+vID).style.display = "";

                  JSGantt.findObj('childgrid_'+vID).style.display = "";

                }



              } else {



                if( JSGantt.findObj('group_'+pID).textContent == 'v') {

                  JSGantt.findObj('child_'+vID).style.display = "";

                  JSGantt.findObj('childgrid_'+vID).style.display = "";

                }

              }

            }



            if(vList[i].getGroup() == 1) 

              JSGantt.show(vID, 0,ganttObj);



          }

        }

      }





  







  // function to open window to display task link

JSGantt.taskLink = function(pRef) 

  {

    if(pRef && pRef != '')

      var OpenWindow=window.open('Projects/PRJRPT.aspx?Chkid='+pRef, "newwin", "height=400,width=600"); 

  }
  
  JSGantt.taskLinkRPT = function(obj,pRef) 

  {

    if(pRef && pRef != '')
      obj.href='Projects/PRJRPT.aspx?Chkid='+pRef; 

  }