/***********************************************************
  Copyright © 2007, InnovaStudio.com. All rights reserved.
************************************************************/

/***************************************************
  Utils:
  - getNumOfColumns
  - getCurrentRowLayout
  - getAbsoluteCellIndex
  - getNextRowLayout
****************************************************/
function getNumOfColumns(oTable)
  {
  var numOfCols=0
  for (var i=0;i<oTable.rows.length;i++)  
    {
    var nCount=0
    var oTR_tmp=oTable.rows[i];
    for (var j=0;j<oTR_tmp.childNodes.length;j++) 
      {
      var oTD_tmp=oTR_tmp.childNodes[j];
      nCount+=oTD_tmp.colSpan
      }
    if(nCount>numOfCols)numOfCols=nCount;
    //alert(numOfCols)
    }
  return numOfCols;
  }
  
function getCurrentRowLayout(oTable, oTR)
  {
  var numOfCols=getNumOfColumns(oTable);
  
  var sTmp="["
  for (var i=1;i<=numOfCols;i++)  sTmp+="false,";
  sTmp=sTmp.substr(0,sTmp.length-1)
  sTmp+="]"
  var arrAllCols = eval(sTmp)

  for(var i=0;i<oTR.rowIndex;i++)//tdk termasuk current row
    {
    var oTR_tmp=oTable.rows[i]
    //alert(oTR_tmp.outerHTML)
    var m=0
    for(var j=0;j<oTR_tmp.childNodes.length;j++)
      {
      var oTD_tmp=oTR_tmp.childNodes[j]
      m+=oTD_tmp.colSpan
      if(oTD_tmp.rowSpan>=oTR.rowIndex+1-i)
        {
        for(var k=0;k<oTD_tmp.colSpan;k++)
          {
          arrAllCols[m-1+k]=true;
          }
        }
      }
    }   
  return arrAllCols;
  }
  
function getAbsoluteCellIndex(oTable,oTR,oTD)//base 1
  {
  var arrAllCols=getCurrentRowLayout(oTable,oTR);
  
  var nCount=0;
  var bFinish=false
  for(var i=0;i<oTR.childNodes.length;i++)
    {
    if(bFinish==false)
      {
      nCount+=oTR.childNodes[i].colSpan
      }
    if(oTD==oTR.childNodes[i])bFinish=true;
    }
  nCount=nCount-(oTD.colSpan-1)
  //alert(nCount)
  for(var i=0;i<nCount;i++)
    {
    if(arrAllCols[i]==true)
      {//alert("OK")
      nCount++;
      }
    }
  var nCellIndex = nCount
  return nCellIndex;
  }
  
function getNextRowLayout(oTable,oTR,oTD)
  {
  var nCellIndex = getAbsoluteCellIndex(oTable,oTR,oTD);//base 1
  var numOfCols=getNumOfColumns(oTable);

  var sTmp="["
  for (i=1;i<=numOfCols;i++) sTmp+="false,";
  sTmp=sTmp.substr(0,sTmp.length-1)
  sTmp+="]"
  var arrTmp= eval(sTmp)

  var bFinish=false
  var oTR_tmp=oTR
  for(var k=0;k<oTD.rowSpan;k++) oTR_tmp=oTR_tmp.nextSibling;
  if(!oTR_tmp) return null
  //alert(oTR_tmp.outerHTML)

  //Navigate rows sblm TR3(target/next row) => TR0, TR1, TR2
  for (var i=0;i<oTR_tmp.rowIndex;i++) 
    {
    var oTR_before=oTable.rows[i]
    // alert(oTR_before.outerHTML)

    for (var j=0;j<oTR_before.childNodes.length;j++) 
      {
      var oTD_before=oTR_before.childNodes[j]; //alert(oTD_before.innerHTML)
      // alert(indx +", CONTENT: " + oTD_before.innerHTML)
            
      /*  kalo TR1 cari rowSpan>=3
        kalo TR2 cari rowSpan>=2
        i+x=oTR_tmp.rowIndex krn base0 & next)
        0+x=3 x=3
        1+x=3 x=2 
        alert(oTD_before.rowSpan + " == " + (oTR_tmp.rowIndex+1-i))//+1 spy base1 krn jumlah*/
      if(oTD_before.rowSpan>=oTR_tmp.rowIndex+1-i)
        {
        for(k=0;k<oTD_before.colSpan;k++)
          {
          // alert("OK" + k)
          var indx=getAbsoluteCellIndex(oTable,oTR_before,oTD_before)
          arrTmp[indx-1+k]=true; //indx-1 krn base indx=1
          }
        }
      }         
    }
  return arrTmp;
  }

/***************************************************
  Span Row
****************************************************/
function spanRow()
  {
  if(!dialogArguments.oUtil.obj.checkFocus()){return;}//Focus stuff
  var oEditor=dialogArguments.oUtil.oEditor;
  var oSel=oEditor.document.selection.createRange();
  var sType=oEditor.document.selection.type;

  var oTable = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TABLE") : GetElement(oSel.item(0),"TABLE"))
  if (oTable == null) return;
  var oTR = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TR") : GetElement(oSel.item(0),"TR"))
  if (oTR == null) return;
  var oTD = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TD") : GetElement(oSel.item(0),"TD"))
  if (oTD == null) return;
  
  var numOfCols=getNumOfColumns(oTable);
  
  var nCellIndex = getAbsoluteCellIndex(oTable,oTR,oTD);//base 1
  
  //Next Row
  oTR_tmp=oTR
  for(var k=0;k<oTD.rowSpan;k++) oTR_tmp=oTR_tmp.nextSibling;
  if(!oTR_tmp) return false;
  //alert(oTR_tmp.outerHTML)
  
  var arrTmp = getNextRowLayout(oTable,oTR,oTD)
  //alert(arrTmp)

  //Cek arrTmp, jumlah true
  nCount=0
  for (i=0;i<nCellIndex;i++) if(arrTmp[i]==true)nCount++;
  numOfTrue=nCount
    
  nCount=numOfTrue
  iResult=0
  bFinish=false
  for (i=0;i<oTR_tmp.childNodes.length;i++)   
    {
    oTD_tmp=oTR_tmp.childNodes[i];
    nCount+=oTD_tmp.colSpan
    if(nCount>=nCellIndex && bFinish==false)
      {
      nCount=nCount-(oTD_tmp.colSpan-1)
      if(nCount==nCellIndex)
        {
        if(oTD_tmp.colSpan==oTD.colSpan)
          {
          nn=oTD_tmp.rowSpan
          //alert(oTD_tmp.innerHTML)
          iResult=i
          bFinish=true
          }
        else return false;
        }
      else return false;
      }
    }
  //alert(iResult)

  nTmp=oTD.rowSpan;
  oTD.rowSpan=oTD.rowSpan+nn; 
  oTR_tmp.deleteCell(iResult);
  return true;
  } 

/***************************************************
  Split Row
****************************************************/
function splitRow()
  {
  if(!dialogArguments.oUtil.obj.checkFocus()){return;}//Focus stuff
  var oEditor=dialogArguments.oUtil.oEditor;
  var oSel=oEditor.document.selection.createRange();
  var sType=oEditor.document.selection.type;

  var oTable = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TABLE") : GetElement(oSel.item(0),"TABLE"))
  if (oTable == null) return;
  var oTR = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TR") : GetElement(oSel.item(0),"TR"))
  if (oTR == null) return;
  var oTD = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TD") : GetElement(oSel.item(0),"TD"))
  if (oTD == null) return;
  
  if(oTD.rowSpan==1) return;//"TD tdk ada rowSpan
  
  var numOfCols=getNumOfColumns(oTable);
  
  var nCellIndex = getAbsoluteCellIndex(oTable,oTR,oTD);//base 1
  
  if(!oTR.nextSibling)return;

  var arrTmp=getCurrentRowLayout(oTable, oTR.nextSibling)
  //alert(arrTmp)
  //Cek arrTmp, jumlah true
  nCount=0
  for (i=0;i<nCellIndex;i++) if(arrTmp[i]==true)nCount++;
  numOfTrue=nCount

  nPoint=nCellIndex-numOfTrue//krn base=1
  //alert("nPoint= "+nPoint)
  
  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  nCount=0
  iResult=0//
  oTR_tmp=oTR.nextSibling;
  bFinish=false
  for (i=0;i<oTR_tmp.childNodes.length;i++)   
    {
    oTD_tmp=oTR_tmp.childNodes[i];
      
    nCount+=oTD_tmp.colSpan

    //alert(nCount + "  " + oTD_tmp.innerHTML)
    if(nCount>nPoint && bFinish==false)
      {
      //alert("    OK")
      iResult=i
      bFinish=true
      }
    else if(bFinish==false)//kalau nCount belum mencapai >nPoint
      {
      //alert("    ambil index terakhir")
      iResult=i+1;
      }     
    }
  //alert(iResult)
    
  nTmp=oTD.rowSpan;
  oTD.rowSpan=1;  
  
  var oNewCell = oTR_tmp.insertCell(iResult);
  oNewCell.innerHTML = "New Cell";
  oNewCell.rowSpan=nTmp-1 
  }

/***************************************************
  Span Column
****************************************************/
function spanCol()
  {
  if(!dialogArguments.oUtil.obj.checkFocus()){return;}//Focus stuff
  var oEditor=dialogArguments.oUtil.oEditor;
  var oSel=oEditor.document.selection.createRange();
  var sType=oEditor.document.selection.type;

  var oTable = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TABLE") : GetElement(oSel.item(0),"TABLE"))
  if (oTable == null) return;
  var oTR = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TR") : GetElement(oSel.item(0),"TR"))
  if (oTR == null) return;
  var oTD = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TD") : GetElement(oSel.item(0),"TD"))
  if (oTD == null) return;
  
  if(oTD.nextSibling)
    {
    if(oTD.rowSpan==oTD.nextSibling.rowSpan)
      {
      oTD.colSpan += oTD.nextSibling.colSpan;
      oTR.deleteCell(oTD.nextSibling.cellIndex);
      }
    }
  }

/***************************************************
  Split Column
****************************************************/
function splitCol()
  {
  if(!dialogArguments.oUtil.obj.checkFocus()){return;}//Focus stuff
  var oEditor=dialogArguments.oUtil.oEditor;
  var oSel=oEditor.document.selection.createRange();
  var sType=oEditor.document.selection.type;

  var oTable = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TABLE") : GetElement(oSel.item(0),"TABLE"))
  if (oTable == null) return;
  var oTR = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TR") : GetElement(oSel.item(0),"TR"))
  if (oTR == null) return;
  var oTD = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TD") : GetElement(oSel.item(0),"TD"))
  if (oTD == null) return;
  
  if(oTD.colSpan==1)return;
  
  //~~~~ OLD ~~~~~~
  //if(!oTD.nextSibling)return; 
  //if(oTD.rowSpan!=oTD.nextSibling.rowSpan)return;
  //~~~~ OLD ~~~~~~

  //~~~~ NEW ~~~~~~
  if(oTD.nextSibling)
    {
    if(oTD.rowSpan!=oTD.nextSibling.rowSpan)return;
    }
  //~~~~ NEW ~~~~~~

  oTD.colSpan--;

  var oNewCell = oTR.insertCell(oTD.cellIndex+1);
  oNewCell.innerHTML = "New Cell";
  }

/************************
  SIZE
************************/
function insertRow(what)
  {
  if(what=="Above") 
    rowOperation(false,true,false,false);
  else
    rowOperation(false,false,true,false);
  }
function insertCol(what)
  {
  if(what=="Left") 
    colOperation(false,true,false,false);
  else
    colOperation(false,false,true,false);
  } 
function delRow()
  {
  rowOperation(false,false,false,true)
  }
function delCol()
  {
  colOperation(false,false,false,true)
  }
  

/***************************************************
  col & row Operation
****************************************************/
function colOperation(bGetArrayCells,bDoInsertColumnLeft,bDoInsertColumnRight,bDeleteColumn)
  {
  if(!dialogArguments.oUtil.obj.checkFocus()){return;}//Focus stuff
  var oEditor=dialogArguments.oUtil.oEditor;
  var oSel=oEditor.document.selection.createRange();
  var sType=oEditor.document.selection.type;

  var oTable = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TABLE") : GetElement(oSel.item(0),"TABLE"))
  if (oTable == null) return;
  var oTR = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TR") : GetElement(oSel.item(0),"TR"))
  if (oTR == null) return;
  var oTD = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TD") : GetElement(oSel.item(0),"TD"))
  if (oTD == null) return;
  
    
  var bCannotDelete=false;
    
  sArrCols=""
  var nCellIndex = getAbsoluteCellIndex(oTable,oTR,oTD);//base 1
  nColSpan=oTD.colSpan
    
  for (var i=0;i<oTable.rows.length;i++)  
    {
    var oTR_tmp = oTable.rows[i];
    arrTmp = getCurrentRowLayout(oTable,oTR_tmp)
    //alert(oTR_tmp.outerHTML)      
    
    if(arrTmp[nCellIndex-1]!=true)//Special case
      {       
      //Cek arrTmp, jumlah true
      nCount=0
      for (j=0;j<nCellIndex;j++) if(arrTmp[j]==true) nCount++;
      numOfTrue=nCount

      nCount=numOfTrue
      bFinish=false
      //alert(numOfTrue + "  " + arrTmp)
      for (k=0;k<oTR_tmp.childNodes.length;k++)   
        {         
        oTD_tmp=oTR_tmp.childNodes[k];
        nCount+=oTD_tmp.colSpan
        if(nCount>=nCellIndex && bFinish==false)
          {           
          nCount=nCount-(oTD_tmp.colSpan-1)
          //alert(nCellIndex + " OK  :  " + nCount + "   " +oTD_tmp.innerHTML)
          if(nCount==nCellIndex)
            {
            //alert(oTD_tmp.innerHTML)  
                        
            //~~~~~~~~~~~~~~~~~~~~~~~~~~
            if(bDoInsertColumnLeft || bDoInsertColumnRight) 
              {
              if(oTD_tmp.colSpan>1) 
                {
                //alert("colspan")  
                oTD_tmp.colSpan=oTD_tmp.colSpan+1;
                }
              else
                {
                if(bDoInsertColumnLeft)
                  {
                  var oNewCell = oTR_tmp.insertCell(oTD_tmp.cellIndex);
                  oNewCell.style.cssText=oTD_tmp.style.cssText;
                  oNewCell.innerHTML = "New Cell";
                      
                  oNewCell.rowSpan = oTD_tmp.rowSpan; 
                  }
                else
                  {
                  var oNewCell = oTR_tmp.insertCell(oTD_tmp.cellIndex+1);
                  oNewCell.style.cssText=oTD_tmp.style.cssText;
                  oNewCell.innerHTML = "New Cell";  
                      
                  oNewCell.rowSpan = oTD_tmp.rowSpan; 
                  }
                }
              }
            //~~~~~~~~~~~~~~~~~~~~~~~~~~              
            
            if(oTD_tmp.colSpan==nColSpan)
              {
              sArrCols += "[" + i + "," + oTD_tmp.cellIndex + "]," 
              }
            else
              {
              sArrCols += "[" + i + "," + oTD_tmp.cellIndex + "]," 
              
              if(bDeleteColumn)
                {
                alert(getTxt("Cannot delete column."));
                return;
                }           
              
              }
            }
          else
            {
            //alert(oTD_tmp.innerHTML)
            
            //~~~~~~~~~~~~~~~~~~~~~~~~~~
            if(bDoInsertColumnLeft || bDoInsertColumnRight) 
              {
              oTD_tmp.colSpan=oTD_tmp.colSpan+1;
              }
            //~~~~~~~~~~~~~~~~~~~~~~~~~~

            if(bDeleteColumn)
              {
              alert(getTxt("Cannot delete column."));
              return;
              }
            }
          bFinish=true
          }         
        }
      }     
    }
  //alert(sArrCols.substring(0,sArrCols.length-1))
    
  var arrCols = eval("["+sArrCols.substring(0,sArrCols.length-1)+"]");
  
  if(bGetArrayCells)
    {
    return arrCols;
    }
  
  if(bDeleteColumn)
    {
    for (var i=0;i<arrCols.length;i++)  
      {
      var rowIndex=arrCols[i][0];
      var colIndex=arrCols[i][1];
      oTable.rows[rowIndex].deleteCell(colIndex);
      }
    }       
  }

function rowOperation(bGetArrayCells,bDoInsertRowAbove,bDoInsertRowBelow,bDeleteRow)
  {
  if(!dialogArguments.oUtil.obj.checkFocus()){return;}//Focus stuff
  var oEditor=dialogArguments.oUtil.oEditor;
  var oSel=oEditor.document.selection.createRange();
  var sType=oEditor.document.selection.type;

  var oTable = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TABLE") : GetElement(oSel.item(0),"TABLE"))
  if (oTable == null) return;
  var oTR = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TR") : GetElement(oSel.item(0),"TR"))
  if (oTR == null) return;
  var oTD = (oSel.parentElement != null ? GetElement(oSel.parentElement(),"TD") : GetElement(oSel.item(0),"TD"))
  if (oTD == null) return;
  
  if(bGetArrayCells)
    {
    var sTmp="[";
    for(var i=0;i<oTR.childNodes.length;i++)
      {
      sTmp += "[" + oTR.rowIndex + "," + oTR.childNodes[i].cellIndex + "],"
      }
    sTmp=sTmp.substr(0,sTmp.length-1) + "]"
    return eval(sTmp);  
    }
  
  
  var bCannotDelete=false;

  var numOfCols=getNumOfColumns(oTable);
  var sTmp="["
  for (var i=1;i<=numOfCols;i++)  sTmp+="[null,false],";
  sTmp=sTmp.substr(0,sTmp.length-1)
  sTmp+="]"
  var arrAllCols = eval(sTmp)

  //Cari yg rowSpannya mengenai current row
  for(var i=0;i<oTR.rowIndex;i++)//tdk termasuk current row
    {
    var oTR_tmp=oTable.rows[i]
    //alert(oTR_tmp.outerHTML)
    var m=0
    for(var j=0;j<oTR_tmp.childNodes.length;j++)
      {
      var oTD_tmp=oTR_tmp.childNodes[j]
      m+=oTD_tmp.colSpan
      if(oTD_tmp.rowSpan>=oTR.rowIndex+1-i)
        {
        for(var k=0;k<oTD_tmp.colSpan;k++)
          {
          //arrAllCols[m-1+k]=true;
          arrAllCols[m-1+k][0]=oTD_tmp;
          arrAllCols[m-1+k][1]=true;
          
          if(bDeleteRow)
            {
            alert(getTxt("Cannot delete row."));
            return;
            }       
          }
        }
      }
    }
    
  //Navigate current row
  nCount=0;
  for(var i=0;i<oTR.childNodes.length;i++)
    {
    var oTD_tmp=oTR.childNodes[i];
    
    while(arrAllCols[nCount][0]!=null)  nCount++
    
    if(nCount<=numOfCols)
      {
      
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      if(bDoInsertRowAbove)
        {
        for(var j=0;j<oTD_tmp.colSpan;j++)
          {
          arrAllCols[nCount+j][0]=oTD_tmp;
          arrAllCols[nCount+j][1]=false;        
          }
        nCount=nCount+j;  
        }
      if(bDoInsertRowBelow)
        {
        if(oTD_tmp.rowSpan>1)
          {
          for(var j=0;j<oTD_tmp.colSpan;j++)
            {
            arrAllCols[nCount+j][0]=oTD_tmp;
            arrAllCols[nCount+j][1]=true;       
            }       
          }
        else
          {
          for(var j=0;j<oTD_tmp.colSpan;j++)
            {
            arrAllCols[nCount+j][0]=oTD_tmp;
            arrAllCols[nCount+j][1]=false;        
            }       
          }     
        nCount=nCount+j;
        }
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      }
    }
    
    
  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  if(bDoInsertRowAbove)
    {
    var oNewRow = oTable.insertRow(oTR.rowIndex);
    }
  if(bDoInsertRowBelow)
    {
    var oNewRow = oTable.insertRow(oTR.rowIndex+1);
    }
  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
  //alert(arrAllCols)
  //Sampai di sini dapat arrAllCols, tapi blm ada pembedaan colSpan

  
  var oTD_Prev=null;
  for(var i=0;i<arrAllCols.length;i++)
    {
    var oTD_tmp=arrAllCols[i][0];
    
    if(oTD_tmp!=oTD_Prev)//ada pembedaan colSpan
      {     
      //alert(oTD_tmp.innerHTML)  
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      if(bDoInsertRowAbove || bDoInsertRowBelow)
        {
        if(arrAllCols[i][1]==true)
          {
          //alert("span")
          oTD_tmp.rowSpan=oTD_tmp.rowSpan+1
          }
        else
          {
          oNewTD = oNewRow.insertCell();
          oNewTD.style.cssText=oTD_tmp.style.cssText;
          oNewTD.innerHTML = "New Cell";
          
          oNewTD.colSpan=oTD_tmp.colSpan;
          }
        }
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      }
    oTD_Prev=oTD_tmp;
    }
  

  if(bDeleteRow)
    {
    oTable.deleteRow(oTR.rowIndex);
    }
  }