/////////////////////////////////////////////////////////////
// Copyright 1999,2000 Amaris Software Entwicklungsges. mbH
// waClientDB.js
// Javascript-Bibliothek für clientseitigen Datensichtzugriff
/////////////////////////////////////////////////////////////

function waClientDB()
{
  // felder initialisieren
  this.tableID=-1;
  this.mask=0;
  
  this.fieldIDs=null;
  this.d=new Array();
  this.m="";
  this.resultIndex=0;
  this.recordCount=-1;
  this.rTabIdx=-1;

  // methoden bekannt machen
  this.init=wa_init;
  this.select=wa_select;
  this.filter=wa_filter;
  this.query=wa_query;
  this.next=wa_next;
  this.get=wa_get;
  this.getIndex=wa_getIndex;
  this.getMask=wa_getMask;
  this.nextField=wa_nextField;
  this.getName=wa_getName;
  this.getType=wa_getType;
  this.setFields=wa_setFields;

  this.itMask=0;
  this.itAllMask=0;
}

function wa_init(SrcTabId)
{
  this.tableID=SrcTabId;
}

function wa_select(fieldMask)
{
  this.m="";
  this.mask=0;
  
  var s;
  firstField=true;
  mask=1;
  for (i=0; i < 32; i++)
  {
    if (fieldMask & mask)
    {
      s="waDB"+this.tableID+"_"+i;
      
      if (eval("typeof "+s) != "undefined")
      { 
        this.mask|=mask;
           
        this.d[i]=eval(s);
      
        // erstes Feld
        if (firstField)
        { // ja => recordCount ermittlen  (Anzahl der Elemente im Array minus 2 (FeldName und FeldTyp)
          this.recordCount=this.d[i].length-2;
          firstField=false;
        }
      }
    }
    
    mask<<=1;
  }  

  this.itAllMask=this.mask;
}

function wa_query(start)
{
  this.rTabIdx=0;
  this.itMask=0;
  
  if(this.m.length > 0)
  {
    while (this.resultIndex < start)
    {
      if (!this.next())
        return;
    }
  }
  else
  {
    this.rTabIdx=start;
  }
}

function wa_next()         // bool
{
  this.itMask=0;

  if (this.m.length > 0)
  {
    while(this.rTabIdx < this.recordCount)
    {
      I=this.rTabIdx;
      if (eval(this.m))
      {
        this.rTabIdx++;
        this.resultIndex++;
        return true;
      }
      this.rTabIdx++;
    }
  
    return false;
  }

  return (this.rTabIdx++ < this.recordCount);
}

function wa_get(mask)  // String
{
  if (mask == 0)
    mask=this.itMask;

  return this.d[wa_mask2Idx(mask)][this.rTabIdx-1];
}

function wa_getIndex()   // int
{
  return (this.rTabIdx-1);
}

function wa_nextField()
{
  if (this.itMask == 0)
    this.itMask=1;
  else
    this.itMask<<=1;

  while (this.itMask != 0)
  {
    if (this.itAllMask & this.itMask)
      return true;

    this.itMask<<=1;
  }
  
  return false;
}

function wa_getName(mask)
{
  if (mask == 0)
    mask=this.itMask;

  return this.d[wa_mask2Idx(mask)][this.recordCount];
}

function wa_getType(mask)
{
  if (mask == 0)
    mask=this.itMask;
    
  return parseInt(this.d[wa_mask2Idx(mask)][this.recordCount+1], 10);
}

function wa_setFields(mask)
{
  this.itAllMask=(mask & this.mask);
  this.itMask=0;
}

function wa_mask2Idx(fieldMask)
{
  mask=1
  for (i=0; i < 32; i++)
  {
    if (fieldMask & mask)
    {
      return i;
    }
    mask<<=1;
  }
  
  alert("illegale feldMaske");
  return -1;
}

function wa_getMask()
{
  return this.itMask;
}


/* Ausdrucksanalyse ab hier */
// Scanner-Token
var waScanTOKEND  = 0;  // Eingabeende
var waScanTOKOR   = 1;  // Oder (nicht case-sensitiv) Or
var waScanTOKAND  = 2;  // Und (nicht case-sensitiv) And
var waScanTOKNOT  = 3;  // Nicht (nicht case-sensitiv) Not
var waScanTOKPO   = 4;  // Klammer auf "("
var waScanTOKPC   = 5;  // Klammer zu ")"
var waScanTOKLIT  = 6;  // Literal oder "Literal"
var waScanTOKGR	  = 7;  // Grösser ">"
var waScanTOKLE	  = 8;  // Kleiner "<"
var waScanTOKEQ	  = 9;  // Gleich  "="
var waScanTOKNEQ  = 10; // Ungleich  "#" oder "<>" oder "><"
var waScanTOKGREQ = 11; // Grössergleich ">=" oder "=>" oder ">   =" oder ...
var waScanTOKLEEQ = 12; // Kleinergleich "<=" oder "=>"

var waScanTok;	  // Gescanntes Token
var waScanTokTxt; // Zugehöriger Tokentext
var waScanTxt;	  // Zu scannender Text
var waScanChr;	  // Gescanntes Zeichen

function waScanNext()
{
  if (waScanTxt.length > 0)
  {
    waScanChr=waScanTxt.substring(0,1);
    waScanTxt=waScanTxt.substring(1);
  }
  else
  {
    waScanChr=0;
  }
  return waScanChr;
}

function waScanToken()
{
var tempstr;

  waScanTokTxt="";
  while (waScanNext()) 
    if (waScanChr != " ")
      break;
  if (!waScanChr)
  {
    waScanTok=waScanTOKEND;
    return waScanTok;
  }
  // Literal
  if (waScanChr == "\"")
  {
    while(waScanNext())
    {
      if (waScanChr != "\"")
   		  waScanTokTxt+=waScanChr;
      else
        break;
    }
    waScanTok=waScanTOKLIT;
    return waScanTok;
  }
  if (waScanChr == "(")
  {
    waScanTok=waScanTOKPO;
    return waScanTok;
  }
  if (waScanChr == ")")
  {
    waScanTok=waScanTOKPC;
    return waScanTok;
  }
  if (waScanChr == "#")
  {
    waScanTok=waScanTOKNEQ;
    return waScanTok;
  }
  if (waScanChr == "=")
  {
    tempstr=waScanTxt;
    waScanToken();
    if (waScanTok == waScanTOKGR)
    {
      waScanTok=waScanTOKGREQ;
    }
    else
    {
      if (waScanTok == waScanTOKLE)
        waScanTok=waScanTOKLEEQ;
      else
      {
        waScanTxt=tempstr;
        waScanTok=waScanTOKEQ;
        waScanTokTxt="";
      }
    }
    return waScanTok;
  }
  if (waScanChr == ">")
  {
    tempstr=waScanTxt;
    if (waScanToken() == waScanTOKEQ)
      waScanTok=waScanTOKGREQ;
    else
    {
  	  if (waScanTok == waScanTOKLE)
	    waScanTok=waScanTOKNEQ;
	  else
	  {
        waScanTxt=tempstr;
        waScanTok=waScanTOKGR;
        waScanTokTxt="";
	  }
    }
    return waScanTok;
  }
  if (waScanChr == "<")
  {
    tempstr=waScanTxt;
    if (waScanToken() == waScanTOKEQ)
      waScanTok=waScanTOKLEEQ;
    else
    {
	  if (waScanTok == waScanTOKGR)
	    waScanTok=waScanTOKNEQ;
	  else
	  {
        waScanTxt=tempstr;
        waScanTok=waScanTOKLE;
        waScanTokTxt="";
	  }
    }
    return waScanTok;
  }
  
  br=true;
  while (br)
  {
    if (" ()=><#".indexOf(waScanChr) >= 0)
    {
      waScanTxt=waScanChr+waScanTxt;
      break;
    }
    waScanTokTxt+=waScanChr;
    br=waScanNext();
  }
  
  scantoktxt=waScanTokTxt.toUpperCase();
  if (scantoktxt.length > 0)
  {
    waScanTok=waScanTOKLIT;
    if ((scantoktxt == "ODER") || (scantoktxt == "OR"))
      waScanTok=waScanTOKOR;
    if ((scantoktxt == "UND") || (scantoktxt == "AND"))
      waScanTok=waScanTOKAND;
    if ((scantoktxt == "NICHT") || (scantoktxt == "NOT"))
      waScanTok=waScanTOKNOT;
  }
  else
    waScanTok=waScanTOKEND;
  return waScanTok;
}

function waExpr2JS(variable,type)
{
var jsCode="";

  jsCode=waTerm2JS(variable,type);
  while ((waScanTok != waScanTOKPC) && (waScanTok != waScanTOKEND))
  {
    if (waScanTok == waScanTOKOR)
    {
      waScanToken();
    };
    jsCode+=" || "+waTerm2JS(variable,type);
  }
  return jsCode;
}

function waTerm2JS(variable,type)
{
var jsCode="";

  jsCode=waOpFactor2JS(variable,type);
  while ((waScanTok == waScanTOKAND) && (waScanTok != waScanTOKEND))
  {
    waScanToken();
    jsCode+=" && "+waOpFactor2JS(variable,type);
  }
  return jsCode;
}

function waOpFactor2JS(variable,type) 
{
var jsCode="";
  if (waScanTok == waScanTOKEQ)
  {
    waScanToken();
    if (waScanTok == waScanTOKLIT)
    {
      if (type == 3)
        jsCode="("+variable+" == "+"\""+parseFloat(waScanTokTxt)*100+"\")";
      else
        jsCode="("+variable+" == "+"\""+waScanTokTxt+"\")";
      waScanToken();
  	  return jsCode;
    }
    else
    {
   	  return "";
    }
  }
  if (waScanTok == waScanTOKLE)
  {
   jsCode="<";
  }
  if (waScanTok == waScanTOKLEEQ)
  {
   jsCode="<=";
  }
  if (waScanTok == waScanTOKGR)
  {
   jsCode=">";
  }
  if (waScanTok == waScanTOKGREQ)
  {
   jsCode=">=";
  }
  if (waScanTok == waScanTOKNEQ)
  {
   jsCode="!=";
  }

  if (jsCode.length > 0)
  {
    waScanToken();
    if (waScanTok == waScanTOKLIT)
    {
      if (type == 2)
        jsCode="(parseFloat("+variable+")"+jsCode+parseFloat(waScanTokTxt)+")";
      else
        if (type == 3)
          jsCode="(parseFloat("+variable+")"+jsCode+parseFloat(waScanTokTxt)*100+")";
        else
          jsCode="("+variable+".toUpperCase()"+jsCode+"\""+waScanTokTxt.toUpperCase()+"\")";
      waScanToken();
	  return jsCode;
    }
    else
    {
   	  return "";
    }
  }

  if (waScanTok == waScanTOKNOT)
  {
    waScanToken();
    return "!("+waOpFactor2JS(variable,type)+")";
  } 
  else
    return waFactor2JS(variable,type);
}

function waFactor2JS(variable,type)
{
var jsCode="";

  if (waScanTok == waScanTOKPO)
  {
    waScanToken();
    jsCode="("+waExpr2JS(variable,type)+")";
    waScanToken();
  }
  else
  {
    if (waScanTok == waScanTOKLIT)
	{
      if (type == 2)
        jsCode="("+variable+" == "+parseInt(waScanTokTxt+0.5)+")";
      else
        if (type == 3)
          jsCode="("+variable+" == "+parseInt(waScanTokTxt*100+0.5)+")";
        else
          jsCode="("+variable+".toUpperCase().indexOf(\""+waScanTokTxt.toUpperCase()+"\") != -1)";
      waScanToken();
    }
  }
  return jsCode;
}

function wa_filter(fieldMask,expression)
{
  if (fieldMask == 0)
  {
    this.m="";
    return;
  }
  if (expression.length > 0)
  {
    waParseError=false;
    waScanTxt=expression;
    waScanToken();
    vartxt="waDB"+this.tableID+"_"+wa_mask2Idx(fieldMask)+"[I]";
    if (this.m.length == 0)
    {
      this.m=waExpr2JS(vartxt,this.getType(fieldMask));
    }
    else
    {
      this.m="("+this.m+") && ("+waExpr2JS(vartxt,this.getType(fieldMask))+")";
    }
  }
  return;
}
