  var GlobalID=1;

  function JSGridID()
  {
    GlobalID++;

    return "jsgridid"+(GlobalID);
  }

  function JSGridRowOnClick(on,id,row)
  {
    var o=eval(on);
    var main_key=document.getElementById(o.Name+"main_key");

    o.SelectRow(row,id);
    main_key.focus();

    o.OnRowClick(row);
  }

  function JSGridRowOnKeyDown(on,id,row)
  {
    var o=eval(on);

    //alert(Number(row)+1);
    o.SelectRow(o.SelectedRowIndex+1);

    return false;
  }

  function JSGridRowsOnScroll(div,on)
  {
    var o=eval(on);

    //alert(div.scrollLeft);
    o.ScrollLeft(div.scrollLeft);

    //o.SelectRow(row);
  }

  function JSGridColResizeStart(evt,colindex,on)
  {
    var o=eval(on);

    o.ResizeColIndex=colindex;
    o.ResizeCol=1;

    //var debug=document.getElementById("debug");
    //debug.innerHTML+=o.ResizeColIndex+"\n";
  }

  function JSGridColResizeEnd(evt,colindex,on)
  {
    var o=eval(on);

    o.ResizeColIndex=colindex;
    o.ResizeCol=0;

    //var debug=document.getElementById("debug");
    //debug.innerHTML+=o.ResizeColIndex+"\n";
  }

  function JSGridColResize(evt,on)
  {
    var o=eval(on);

    if(o.ResizeCol)
    {
      var x=0; //o.Left;

      var oo=document.getElementById('o'+o.ID);

      var ox=GetLeft(oo,0);
      var mx= document.all ? window.event.clientX : evt.pageX;
      var my= document.all ? window.event.clientY : evt.pageY;

      var table_container=document.getElementById(o.RowsDivID);

      for(var i=0;i<o.ResizeColIndex;i++)
        x+=o.ColWidth[i]+2;

      var width=o.ColWidth[o.ResizeColIndex]+mx-x+table_container.scrollLeft-2;

      var debug=document.getElementById("debug");
      debug.innerHTML+=o.ColWidth[o.ResizeColIndex]+"/"+width+"("+ox+"/"+mx+")\n";

      width=mx-ox-2-x+table_container.scrollLeft;

      //width=mx-ox;
      //o.SetColWidth(o.ResizeColIndex,w);
      o.SetColWidth(o.ResizeColIndex,width);
    }
  }

  function JSGrid()
  {
    this.Rows=new Array();
    this.Columns=new Array();
    this.RowID=new Array();
    this.ColID=new Array();
    this.ColHeaderID=new Array();
    this.ColWidth=new Array();

    this.Show=Show;
    this.Init=Init;
    this.SelectRow=SelectRow;
    this.ScrollLeft=ScrollLeft;
    this.SetRows=SetRows;
    this.SetCols=SetCols;
    this.SetColWidths=SetColWidths;
    this.GetRows=GetRows;
    this.GetCols=GetCols;
    this.RowOnKeyDown=RowOnKeyDown;
    this.RowUp=RowUp;
    this.RowDown=RowDown;
    this.PageUp=PageUp;
    this.PageDown=PageDown;

    this.OnRowSelect=OnRowSelect;
    this.OnRowClick=OnRowClick;
    this.SetRowIndex=SetRowIndex;
    this.SetColWidth=SetColWidth;
    this.SetColVisible=SetColVisible;
    this.SetColCaption=SetColCaption;

    this.SetRowHeight=SetRowHeight;

    this.ShowWait=ShowWait;

    var ResizeColIndex;
    var ResizeGripImage;

    function ShowWait()
    {
      var rows_o=document.getElementById(this.RowsDivID);
      rows_o.innerHTML="bitte warten ...";
    }

    function OnRowSelect(rowindex)
    {
      // prototyp
    }

    function OnRowClick(rowindex)
    {
      // prototyp
    }

    function SetRowIndex(rowindex)
    {
      //alert(this.ID);
      this.SelectRow(rowindex);
    }

    function SetRowHeight(height)
    {
      var o;
      for(var i=0;i<this.RowCount;i++)
      {
        o=document.getElementById(this.RowID[i]);
        o.style.height=height+'px';
      }

      this.RowHeight=height;

      //this.SelectRow(rowindex);
    }

    function SetColVisible(colindex,visible)
    {
      var _visible="none";
      var _hcolindex=colindex*2;
      var _colindex=colindex;

      if(visible=="True")
        _visible="";

      var o=document.getElementById("t"+this.Name);
      var oh=document.getElementById("th"+this.Name);

      if(o)
      {
        var rows=o.rows;

        if(rows)
          for(i=0;i<rows.length;i++)
            rows[i].cells[_colindex].style.display=_visible;
      }

      if(oh)
      {
        var rowsh=oh.rows;

        if(rowsh)
          for(i=0;i<rowsh.length;i++)
          {
            rowsh[i].cells[_hcolindex].style.display=_visible;
            rowsh[i].cells[_hcolindex+1].style.display=_visible;
          }
      }
    }

    function SetColWidth(colindex,width)
    {
      var oh=document.getElementById(this.ColHeaderID[colindex]);
      var o=document.getElementById(this.ColID[colindex]);

      //if(width!="" && oh && o)
      if(!width)
        width="0";

      if(oh && o)
      {
        oh.style.width=width+"px";
        if(browserFF)
          o.style.width=(width+8)+"px";
        else
          o.style.width=(width+2)+"px";
      }

      this.ColWidth[colindex]=width;

      //alert(colindex+"="+width);
    }

    function SetColCaption(colindex,caption)
    {
      var oh=document.getElementById(this.ColHeaderID[colindex]);
      var o=document.getElementById(this.ColID[colindex]);

      oh.innerHTML="<nobr>"+caption+"</nobr>";
    }

    function PageDown()
    {
      var table_container=document.getElementById(this.RowsDivID);
      var rows_per_page=Math.round(table_container.offsetHeight/this.ColumnsRowHeight)-2;
      this.SelectRow(this.SelectedRowIndex+rows_per_page);
    }

    function PageUp()
    {
      var table_container=document.getElementById(this.RowsDivID);
      var rows_per_page=Math.round(table_container.offsetHeight/this.ColumnsRowHeight)-2;
      this.SelectRow(this.SelectedRowIndex-rows_per_page);
    }

    function RowUp()
    {
      this.SelectRow(this.SelectedRowIndex-1);
    }

    function RowDown()
    {
      this.SelectRow(this.SelectedRowIndex+1);
    }

    function SelectRow(row,id)
    {
      var isDebug=0;

      row=Number(row);

      if(row<0)
        row=0;
      if(row>this.RowCount-1)
        row=this.RowCount-1;
      //alert(row);

      var debug="";

      var table_container=document.getElementById(this.RowsDivID);

      var view_top=table_container.scrollTop;
      var view_bottom=table_container.scrollTop+table_container.offsetHeight-20;
      var view_row_top=row*this.RowHeight;
      var view_row_bottom=(row+1)*this.RowHeight;

      //table_container.scrollTop=row*this.ColumnsRowHeight;
      //var offset=this.ColumnsRowHeight-(table_container.offsetHeight-(row+1)*this.ColumnsRowHeight);

      if(isDebug)
      {
        debug+="view_top:"+view_top+"\nview_bottom:"+view_bottom+"\n";
        debug+="view_row_top:"+view_row_top+"\nview_row_bottom:"+view_row_bottom+"\n";
      }

      /*
      if(offset>0)
        table_container.scrollTop=offset;
      */

      //eval('alert(window.all)'); .'+this.RowsDivID).innerHTML="moin";

      //table_container.scrollTo(0,10);
      //alert(table_container);

      if(!id)
        id=this.RowID[row];
      //alert(id);
      var new_row_o=document.getElementById(id);
      if(new_row_o)
      {
        var old_row_o=document.getElementById(this.SelectedRowID);

        if(old_row_o)
          old_row_o.className='Row';

        new_row_o.className='RowSelected';

        var ud=true;

        if(this.SelectedRowIndex<row)
          ud=false;

        //alert(ud);
        //new_row_o.scrollIntoView(ud);

        this.SelectedRowIndex=row;
        this.SelectedRowID=id;

        this.OnRowSelect(row);
      }
      //alert(new_row_o.offsetY);

      if(isDebug)
      {
        var d=document.getElementById("debug");
        d.value=debug;
      }

      if(view_row_bottom>view_bottom)
        table_container.scrollTop+=view_row_bottom-view_bottom;
      if(view_row_top<view_top)
        table_container.scrollTop-=view_top-view_row_top;

    }

    function ScrollLeft(left)
    {
      var columns_o=document.getElementById(this.ColsDivID);
      //this.RowsDivID=JSGridID();
      columns_o.style.left='-'+left+'px';
      //alert(columns_o.id);
    }

    function SetRows(rows)
    {
      var rows_o=document.getElementById(this.RowsDivID);

      this.Rows=rows;
      rows_o.innerHTML=this.GetRows();
    }

    function SetColWidths(widths)
    {
      if(!this.Lengths)
        this.Lengths=new Array();

      for(var j=0;j<widths.length;j++)
        this.SetColWidth(j,widths[j]);
    }

    function SetCols(cols)
    {
      var cols_o=document.getElementById(this.ColsDivID);
      this.Columns=cols;

      if(!this.Lengths)
        this.Lengths=new Array();

      for(var j=0;j<this.Columns.length;j++)
      {
        if(!this.Lengths[j])
          this.Lengths[j]=10;
      }

      cols_o.innerHTML=this.GetCols();
    }

    function Init()
    {
      this.ColumnsRowHeight=this.TitleFont_Size*1.8;
      this.ColumnsFontFamily="Ms Sans Serif";
      this.ColumnsFontSize=this.ColumnsRowHeight/2;

      this.RowHeight=this.Font_Size*1.8;
      this.RowFontFamily="Ms Sans Serif";
      this.RowFontSize=this.RowHeight/2;
    }

    function GetRows()
    {
      var rows="";
      var cell_str="";

      //if(this.RowID)
      this.RowID=new Array();
      this.RowCount=0;

      var table_width=0;

      if(this.Lengths)
        for(var j=0;j<this.Lengths.length;j++)
          table_width+=this.Lengths[j];

      rows+="<table id=\"t"+this.Name+"\" cellpadding=\"2\" cellspacing=\"0\" style=\"table-layout:fixed; width:"+table_width+"px;\">";

      if(this.Rows)
      for(var j=0;j<this.Rows.length;j++)
      {
        if(this.Rows[j])
        {
          this.RowID[j]=JSGridID();

          rows+="<tr id=\""+this.RowID[j]+"\" "+
                "    class=\"Row\" style=\"height:"+this.RowHeight+"px; font-size:"+this.RowFontSize+"px; font-family:'"+this.RowFontFamily+"';\" "+
                //"    onKeyDown=\"JSGridRowOnKeyDown('"+this.Name+"','"+this.RowID[j]+"', '"+j+"'); return false;\" "+
                "    onClick=\"JSGridRowOnClick('"+this.Name+"','"+this.RowID[j]+"', '"+j+"'); return false;\">";
          for(var i=0;i<this.Rows[j].length;i++)
          {
            //rows+="<td>"+this.Rows[i][j]+"</td>";
            cell_str=this.Rows[j][i];
            if(!cell_str)
              cell_str="&nbsp;";

            if(j==0)
            {
              this.ColID[i]=JSGridID();

              rows+="<td class=\"RowCell\" id=\""+this.ColID[i]+"\" style=\"color:"+this.Font_Color+"; font-size:"+this.Font_Size+"; font-family:"+this.Font_Name+"; width:"+(this.ColWidth[i]+2)+"px;\"><nobr>"+cell_str+"</nobr></td>";
            }
            else
              rows+="<td class=\"RowCell\" style=\"color:"+this.Font_Color+"; font-size:"+this.Font_Size+"; font-family:"+this.Font_Name+"\"><nobr>"+cell_str+"</nobr></td>";
          }
          rows+="</tr>";

          this.RowCount++;
        }
      }

      rows+="</table>";

      return rows;
    }

    function GetCols()
    {
      var columns="";
      var table_width=0;
      if(this.Lengths)
        for(var j=0;j<this.Lengths.length;j++)
          table_width+=this.Lengths[j];

      columns+="<table id=\"th"+this.Name+"\" cellpadding=\"0\" cellspacing=\"0\" style=\"table-layout:fixed; width:"+table_width+"px;\">";
      columns+="<tr class=\"ColumnsRow\" "+
               "    onmousemove=\"JSGridColResize(event,'"+this.Name+"');\" "+
               "    onclick=\"JSGridColResizeEnd(event,-1,'"+this.Name+"');\" "+
               "    style=\"height:"+this.ColumnsRowHeight+"px; font-size:"+this.ColumnsFontSize+"px; font-family:'"+this.ColumnsFontFamily+"';\" "+
               ">";

      for(var i=0;i<this.Columns.length;i++)
      {
        this.ColHeaderID[i]=JSGridID();
        if(!this.ColWidth[i])
        {
          this.ColWidth[i]=(this.Lengths[i]*6);
        }

        offset=0;
        if(browserFF)
          offset=-6;

        columns+="<td id=\""+this.ColHeaderID[i]+"\" "+
                 "    class=\"ColumnsRowCell\" "+
                 "    style=\"height:"+this.ColumnsRowHeight+"px; width:"+(offset+this.ColWidth[i])+"px; color:"+this.TitleFont_Color+"; font-size:"+this.TitleFont_Size+"; font-family:"+this.TitleFont_Name+"; \"><nobr>"+this.Columns[i]+"</nobr></td>";
        columns+="<td style=\"width:2px; cursor:e-resize;\">"+
                 "  <img width=\"2\" "+
                 "       height=\""+this.ColumnsRowHeight+"\" "+
                 "       ondragstart=\"return false;\" "+
                 "       ondrag=\"return false;\" "+
                 "       src=\""+this.ResizeGripImage+"\" "+
                 "       onmousedown=\"JSGridColResizeStart(event,"+i+",'"+this.Name+"');\""+
                 "       onmouseup=\"JSGridColResizeEnd(event,"+i+",'"+this.Name+"');\""+
                 "       onclick=\"JSGridColResizeEnd(event,"+i+",'"+this.Name+"');\""+
                 "></td>";
      }
      columns+="</tr>";
      columns+="</table>";

      return columns;
    }

    function Show()
    {
      this.Init();

      // Columns

      columns=""; //this.GetCols();

      // /Columns

      // Rows
      //alert(C);

      var rows=""; //this.GetRows();

      // /Columns

      //alert(this);
      this.ColsDivID=JSGridID();
      this.RowsDivID=JSGridID();

      document.write("<div style=\"position:absolute; height:0px;\"><input style=\"width:0px;\" id=\""+this.Name+"main_key\" onKeyDown=\""+this.Name+"OnRowKeyDown(event)\"></div><div style=\"position:absolute; overflow:hidden; width:"+this.Width+"px; height:"+this.Height+"px; border:2px inset; background-color:white;\">");
        document.write("<div style=\"position:absolute;\" id=\""+this.ColsDivID+"\">");
          document.write(columns);
        document.write("</div>");
        document.write("<div id=\""+this.RowsDivID+"\" onScroll=\"JSGridRowsOnScroll(this,'"+this.Name+"')\" style=\"position:absolute; overflow:auto; top:"+(this.ColumnsRowHeight+0)+"px; width:"+(this.Width-3)+"px; height:"+(this.Height-this.ColumnsRowHeight-3)+"px; border:0px solid red;\">");
          document.write(rows);
        document.write("</div>");
      document.write("</div>");

      document.write("<script language='javascript'>"+
                     "  var table_container=document.getElementById('"+this.RowsDivID+"'); "+
                     //"  alert(table_container); "+
                     //"  table_container.onkeydown = mytest; "+
                     "  function "+this.Name+"OnRowKeyDown(evt) "+
                     "  { "+
                     //"    alert(0); "+
                     "    var scope=eval('"+this.Name+"'); "+
                     "    evt=(evt) ? evt : ((event) ? event : null); "+
                     "    scope.RowOnKeyDown(evt.keyCode); "+
                     "    return false; "+
                     "  } "+
                     "</script>");


      var table_container=document.getElementById(this.RowsDivID);
      //alert(this.id);
      /*
      table_container.onkeydown = function(evt)
      {
        evt=(evt) ? evt : ((event) ? event : null);

        alert(o);

        if(evt)
          alert(evt.keyCode);
      } //this.showDown;
      */

      this.SelectRow(0);
    }

    function RowOnKeyDown(key)
    {
      if(key==33)
        this.PageUp();
      else if(key==34)
        this.PageDown();
      else if(key==38)
        this.RowUp();
      else if(key==40)
        this.RowDown();
      //else
      //  alert(key);

      return false;
    }
  }