//dataset.Fields.Field[fieldname].Value是根据字段名取值
//dataset.Fields.Fieldx[index].Value是根据字段序号取值
var szRowState="RowState",szRowNo='RowNo',szNested="nested",szDel="2",szNew="4",szOrg="1",szMod="8",szDetUpd="64";
function Query(name,parent) 
{
    var obj=document.createElement('jclquery');
	document.body.appendChild(obj);
	obj.Name=name;
	obj.OpenUrl;
	obj.PostUrl;
	obj.pDets=null;
	obj.LinkObj=function(obj){if(this.linkobjs==null)this.linkobjs=new Array();this.linkobjs[this.linkobjs.length]=obj;if(this.Active==true){obj.HandleMessage(this,0);}}
	obj.RemoveLink=function(obj){var a=this.linkobjs;for(var i=0;i<a.length;i++)if(a[i]==obj){this.linkobjs=_arrayremove(a,i);obj.HandleMessage(this,7);break;}}

	obj.Notify=function(act,recno,p){var os=this.linkobjs;if(!os||this.AutoControl==false)return;for(var j=0;j<os.length;j++)if(os[j].HandleMessage)os[j].HandleMessage(this,act,recno,p);}
	obj.Fields=null;//字段列表对象，可以用dataset.Fields.Field或dataset.Fields.Fieldx访问字段对象
	obj.SetPos=null;//记录定位，用法：SetPos(记录号)
	obj.Bof=true;//是否到记录头
	obj.Eof=false;//是否到记录尾
	obj.AutoControl=true;//是否自动控制感应控件刷新
	obj.MakeRow=QRY_makerow;
	obj.First=function(){return this.SetPos(-1);}//到第一条记录
	obj.Next=function(){return this.SetPos(this.RecNo+1);}//下一条记录
	obj.Prev=function(){return this.SetPos(this.RecNo-1);}//上一条记录
	obj.Last=function(){return this.SetPos(this.RecordCount);}//最后一条记录
	obj.Append=QRY_append;//增加记录
	obj.Edit=function(){this.postall();if(!this.Fields.State&&this.Fields.State!=szNew)if(this.RecordCount==0)this.Append();else this.Fields.State=szMod;}//修改记录，使记录进行修改模式
	obj.Delete=QRY_delete;//删除当前记录
	obj.Cancel=QRY_cancel;//取消所有修改
	obj.Post=QRY_post;//提交数据到数据集中
	obj.Apply=QRY_apply;//真正提交数据到服务器上
	obj.Open=QRY_open;//打开数据集
	obj.GetPackage=QRY_getpackage;//获取一段数据，用法为.GetPackage(起始记录号)
	obj.Close=QRY_close;
	obj.Params=new Params();//参数集，参考它的类定义
	obj.Database;//关联的数据库对象
	obj.SQL;//sql等信息，参见JBUILDER
	obj.MasterLink;//关联的主表
	obj.MasterFields;//主表联接信息
	obj.DetailFields;//从表联接信息
	obj.MaxRows=10;//一次取的记录数
	obj.Xml;//XML数据
	obj.RecordCount=0;//记录总数
	obj.SRecordCount=0;//实际的记录总数
	obj.Locate=QRY_locate;//根据字段名查找记录方法
	obj.OnCalcFields;//计算事件
	obj.Active=false;
	obj.ReadOnly=false;

  obj.onpropertychange=QRY_onpropertychange;//属性变化的事件
  obj.makequery=QRY_makequery;obj.RecNo=0;//当前记录位置
  obj.MetaData=null;
  obj.Data=null;obj.FieldCount=0;obj.FieldData=null;
  obj.RocordCount=0;
  obj.Fields=new Fields(obj);
  obj.detailfields=new Fields(obj);obj.masterfields=new Fields(obj);
  obj.initkey=QRY_initkey;obj.resetdets=QRY_resetdets;
  obj.insert=QRY_insert;obj.modify=QRY_modify;obj.updaterow=QRY_updaterow;
  obj.SetPos=QRY_setpos;obj.initfields=QRY_initfields;
  obj.root=null;obj.newopen=true;obj.applys=QRY_applys;
  obj.InitDataSet=QRY_initdataset;obj.postall=QRY_postall;obj.init=QRY_init;
  if(name){var s='window.'+name+'=obj';eval(s);}
  return obj;
}
function QRY_open()
{
  if(this.Xml==null){
	if(!this.queryxml)this.queryxml=new ActiveXObject('Microsoft.XMLDOM');
	var q=this.queryxml;
	if(q.documentElement)q.removeChild(q.documentElement);
    if(!this.MasterLink){
    el=q.createElement('QUERYPACKET');el.setAttribute('Version','1.0');
    q.appendChild(el);root=el;
    el=q.createElement('DATABASES');
    root.appendChild(el);db=el;
    el=q.createElement('QUERYS');
    root.appendChild(el);qr=el;
	this.makequery(q,db,qr);
    }
  }
//  this.AutoControl=true;
  this.GetPackage();
  if(this.OnAfterOpen)this.OnAfterOpen(this);
}
function QRY_makequery(q,db,qr)
{
  var p,s,el,d=this.Database;
  if(d){
   el=q.createElement('DATABASE');var exist=false;
   s=d.Name;
  for(var i=0;i<db.childNodes.length;i++){
	if(db.childNodes.item(i).getAttribute('name')==s){exist=true;break;}
  }
  if(exist==false){
	el.setAttribute('name',d.Name);
	el.setAttribute('alis',d.AliasName);
	el.setAttribute('connectionurl',d.Url);
	el.setAttribute('driver',d.Driver);
    db.appendChild(el);
  }
  }
  el=q.createElement('QUERY');
  s=this.Name;if(s)el.setAttribute('name',s);
  if(d){s=d.Name;el.setAttribute('database',s);}
  s=this.SQL;if(s)el.setAttribute('query',s);
  s=this.BeanName;if(s)el.setAttribute('beanname',s);
  s=this.MaxRows;if(s)el.setAttribute('maxrows',s);
  s=this.RecNo;if(s)el.setAttribute('recno',s);s=null;
  if(this.MasterLink)s=this.MasterLink.Name;if(s){el.setAttribute('masterlink',s);}else el.setAttribute('masterlink','');
  s=this.MasterFields;if(s)el.setAttribute('masterfield',s);
  s=this.DetailFields;if(s)el.setAttribute('detailfield',s);
  qr.appendChild(el);p=el;this.qrynode=el;
  var l=this.Params.Count;
  if(l>0){el=q.createElement('PARAMS');p.appendChild(el);p=el;}
  for(var i=0;i<l;i++){
    el=q.createElement('PARAM');
    s=this.Params.Paramx[i].Name;if(s)el.setAttribute('name',s);
	s=this.Params.Paramx[i].Value;if(s)el.setAttribute('value',s);
	s=this.Params.Paramx[i].Type;if(s)el.setAttribute('type',s);
	p.appendChild(el);
	
  } 
  if(this.pDets)
	for(var i=0;i<this.pDets.length;i++)this.pDets[i].makequery(q,db,qr);
}
function QRY_getpackage(pos)
{
 if(this.DeltaChanges)if(this.DeltaChanges.row.length>0)this.Cancel();
 if(this.Fields.State&&this.Xml)this.Cancel();
 var el,n,root,s1,s='';var open;
 if((pos)&&(pos>=0))this.RecNo=pos;else this.RecNo=0;
 var q=this.queryxml;
 if(this.newopen==true){
  var pi = q.createProcessingInstruction("xml"," version=\"1.0\" encoding=\"GB2312\"");
  q.insertBefore(pi,q.firstChild);
 }
 el=this.qrynode;s1=this.RecNo;if(el)el.setAttribute('recno',s1);
//  alert(q.xml);
//  document.writeln(q.xml);

  var url=this.OpenUrl;
  if(!url){alert(this.Name+Err_NoURL);return -1;}
  var httpob = new ActiveXObject("Microsoft.XMLHTTP");
  httpob.Open("POST",url, false);
  httpob.send(q);
 try{
  var o=httpob.responseXML;
//  alert(httpob.responseText);
//  alert(o.xml);
//  document.writeln(o.xml);
  if(!o)throw this.Name+Err_NoURL;
  if(o.parseError.errorCode!=0||!o.xml){throw this.Name+Err_NoURL+":"+httpob.responseText;}
  var msg=o.documentElement;
  var errorcode=msg.getAttribute("errorcode");
  if(errorcode!='0'&&errorcode!=null){throw this.Name+':'+msg.getAttribute("message");}
  if (o){this.Xml=o;}
  this.RecNo=0;this.init();
 }catch(e){q.removeChild(q.firstChild);jcl_err(e);}
}
function QRY_init()
{
 try{
 if(this.Xml==null){if(this.MasterLink!=null)this.Xml=this.MasterLink.Xml;else return -1;}
 if(this.Xml==null)if(this.MasterLink==null){throw this.Name+Err_OpenErr;}
 this.oldxml=null;
 this.InitDataSet();
 this.DeltaChanges.reset();
 if(!this.MasterLink){this.idx.sort(null);}
 var dets=this.pDets;
 if(dets)
  for(var i=0;i<dets.length;i++){dets[i].init();} 
 this.Active=true;
 if(!this.MasterLink){ 
  this.SRecordCount=this.Data.getAttribute('recordcount');
  this.RecNo=-2;this.First();
  if(this.newopen==true){this.newopen=false;this.Notify(0);}else this.Notify(5);
 }
 }catch(e){jcl_err(e);}
}
function QRY_close()//关闭数据集
{
 if(this.Active==false)return;
 this.RecNo=0;this.Xml=null;this.Data=null;this.queryxml=null;this.newopen=true;
 this.Fields.Clear();this.masterfields.Clear();this.detailfields.Clear();
//this.Params.Clear();
 var dets=this.pDets;if(dets)for(var i=0;i<dets.length;i++){dets[i].Close();}
 this.Active=false;
 this.Notify(7);
// this.AutoControl=false;
}
function QRY_onpropertychange()//属性变化的事件
{
  var n=event.propertyName;
  switch(n){
	case 'MasterLink':
	  if(this.MasterLink!=null){
	    this.masterfields.DataSet=this.MasterLink;
		if(this.MasterLink.pDets==null)this.MasterLink.pDets=new Array();
		this.MasterLink.pDets[this.MasterLink.pDets.length]=this;
		this.InitDataSet=QRY_initdetaildataset;
	  }
	  break;
  }
}
function QRY_initdataset()
{
  if((this.Xml==null)||(this.Xml.xml==''))return -1;
  var i;
  this.root=this.Xml.documentElement;
  if(this.root==null)return -1;
  if(this.root.tagName=="DATAPACKET"){
    this.MetaData=this.root.childNodes.item(0); 
    this.Data=this.root.childNodes.item(1);
    this.FieldData=this.MetaData.childNodes.item(0);
    this.FieldCount=this.FieldData.childNodes.length;
    if(!this.Active){this.initfields();}
  }
  else{this.Data=this.root;}
  this.RecordCount=this.Data.childNodes.length;
  this.oldxml=this.Xml.xml;
  if(this.DeltaChanges==null)this.DeltaChanges=new DeltaChanges(this);
  if(this.idx==null)this.idx=new idx(this);
}
function QRY_initdetaildataset()
{
  var i;
  var p=this.MasterLink;
  if(p.FieldData){
  var fd=p.FieldData.childNodes;
  var l=fd.length;
  var det=p.Fields.Field[this.Name].node;
  this.FieldData=det.childNodes.item(0);
  if(this.FieldData==null)return -1;
  this.FieldCount=this.FieldData.childNodes.length;
  }
  if(!this.Active)this.initfields();
  if(this.DeltaChanges==null)this.DeltaChanges=new DeltaChanges(this);
  if(this.idx==null)this.idx=new idx(this);
}
function QRY_initfields()
{
 var f;
 var ms=this.MasterFields;var ks=this.DetailFields;
 if (this.oldxml==null){
  for(var i=0;i<this.FieldCount;i++){
   f=new Field(null,this.FieldData.childNodes.item(i));
   if(this.Fields.Auto==true)this.Fields.Add(f);
   else if(f.Type==szNested)this.Fields.Add(f);
  }
  if(this.MasterLink)this.initkey(ms,this.masterfields,this.MasterLink);
  if(ks)this.initkey(ks,this.detailfields);
 }
 this.Fields.State=null;
}
function QRY_initkey(s,k,md)
{
 var f,x=1;if(md)fs=md.Fields;else fs=this.Fields;
 while(x>-1)
 {
  x=s.indexOf(';');
  if(x>-1){
	s=s.substring(0,x);
    f=fs.Field[s];
	if(!f)throw s+Err_NoField;
	k.Add(f,1);
	s=s.substr(x+1,s.length-x);
  }
 }    
 if(s!=''){
   f=fs.Field[s];
   if(!f)throw s+Err_NoField;
   k.Add(fs.Field[s],1);
 }
}
function QRY_resetdets()
{
if(this.pDets==null)return;
if(this.AutoControl==false)return;
var l=this.pDets.length;
for(var i=0;i<l;i++)
{
 var rsd=this.pDets[i];
 var row=this.idx.row(this.RecNo);
 var det=findcnode(row,rsd.Name);
 rsd.Data=det;rsd.queryxml=this.queryxml;
 rsd.oldxml=this.oldxml;
 rsd.RecordCount=(det==null)?0:det.childNodes.length;
 if(rsd.idx)rsd.idx.sort(null);
 if(rsd.Data)rsd.SRecordCount=rsd.Data.getAttribute('recordcount');
 QRY_resetkey(rsd);
 rsd.RecNo=-1;
 if(this.Fields.State==szNew&&rsd.RecordCount<=0)return -1;
 rsd.First();
 rsd.resetdets();
 if(rsd.newopen==true){rsd.newopen=false;rsd.Notify(0);}else rsd.Notify(5);
}
}
function QRY_resetkey(ds)
{
 var ms=ds.MasterFields;var ks=ds.DetailFields;
 var msa=ds.masterfields;var ksa=ds.detailfields;
 if(ms)
  for(var j=0;j<msa.Count;j++){
   ksa.Fieldx[j].Default=msa.Fieldx[j].Value;
  }
}
function QRY_setpos(pos)
{ 
  this.Bof=false;this.Eof=false;
  if(pos>=this.RecordCount)this.Eof=true;
  if(pos>=this.RecordCount)pos=this.RecordCount-1;
  if(pos<0)pos=0;
  if(pos==0)this.Bof=true;
  if(this.RecordCount==0){
    for (var i=0;i<this.Fields.Count;i++){var f=this.Fields.Fieldx[i];f.SetValue(null);}
	this.Fields.State=null;
  }
  var re=0;
  if(this.RecNo!=pos){
	re=this.Post();
	if (re==-1)return -1;
    re=this.postall();if (re==-1)return -1;
	this.RecNo=pos;
	this.MakeRow(pos);
    this.resetdets();
	if(this.OnScroll)this.OnScroll(this);
  }
  this.Notify(3,pos);
  return 0;
}
function QRY_locate(fn,v)
{
  for(var i=this.RecNo;i<this.RecordCount;i++){
	if(this.Fields.Field[fn].Value==v)return true;
	this.Next();
  }
  return false;
}
function QRY_makerow(pos)
{
  var f,r=this.idx.row(pos);
  this.Fields.State=null;if(!r)return;
  for (var i=0;i<this.Fields.Count;i++){
    f=this.Fields.Fieldx[i];
	if (f.FieldKind=='DATA'&&f.Type!=szNested){
      f.SetValue(f.Get(r));f.OldValue=f.Value;
	}
  }
  for (var i=0;i<this.Fields.Count;i++){
    f=this.Fields.Fieldx[i];
	if (f.FieldKind!='DATA')f.SetValue(f.Get(r));
  }
  if(this.OnCalcFields)this.OnCalcFields(this);
}
function QRY_append()
{
  var m=this.MasterLink;var re;if(m)re=m.Post();if(re==-1)return -1;
  if(m)if(m.RecordCount<=0){m.Append();}
  if(m)QRY_resetkey(this);
  var fn=false;var t=this.Fields.State;
  for (var i=0;i<this.Fields.Count;i++){var f=this.Fields.Fieldx[i];;if(f.Value)fn=true;}
  if(t)if(t==szNew&&fn==false)return;else if(this.Post()==-1)return -1;
  
  if(this.FieldData==null)return null;
  var rname="ROW";
  if(m)rname+=this.Name;
  var r=this.Xml.createElement(rname);
  var i,f;
  if(!this.Data){
	this.Data=this.Xml.createElement(this.Name);
	var data=m.idx.row(m.RecNo);
	if(!data){m.Append();data=m.idx.row(m.RecNo);}
	data.appendChild(this.Data);
  }
  this.Data.appendChild(r);
  this.RecordCount++;
  var pos=this.RecordCount-1;
  this.idx.add(pos);
  r=this.idx.row(pos);
  if(r)r.setAttribute(szRowState,szNew);else return -1;
  if(this.pDets){
    var i,l=this.Fields.Count;
    for(i=0;i<l;i++){
	 if(this.Fields.Fieldx[i].Type==szNested){
	  var el=this.Xml.createElement(this.Fields.Fieldx[i].FieldName);r.appendChild(el);
	 }
	}
  }
  var st=this.AutoControl;
  this.AutoControl=false;
  this.SetPos(pos);this.Fields.State=szNew;
  this.AutoControl=st;
  for (var i=0;i<this.Fields.Count;i++){
    var f=this.Fields.Fieldx[i];
    if(f.Default)f.SetValue(f.Default);
  }
  if(this.OnNewRecord)this.OnNewRecord(this);
  this.Notify(1,pos);//this.Notify(3,pos);
  this.resetdets();
}
function QRY_insert(m)
{
  var r=this.idx.row(this.RecNo);
  if(!r)return -1;
  if(this.updaterow(r)==-1)return -1;
  this.DeltaChanges.add(szNew,r,null,this);
  this.idx.chg=1;this.Fields.State=null;
  if(r.attributes.length<=1){this.Delete();return -1;}
  this.Notify(6,this.RecNo);	
  return 0;
}
function QRY_updaterow(r)
{
  var f;
  for(var i=0;i<this.Fields.Count;i++){
   f=this.Fields.Fieldx[i];
   if(f.FieldKind=='DATA')f.Put(r);
  }
}
function QRY_delete()
{ 
  try{
  if(this.Fields.State)if(this.Post()==-1)return -1;
  var spos=this.RecNo;var pos=spos;
  var r=this.idx.row(pos);
  if(r==null)return 1;
  var i,l=r.childNodes.length;
  if(l&&this.pDets)
    for(i=0;i<this.pDets.length;i++){
      var det=findcnode(r,this.pDets[i].Name);
      if(det&&det.childNodes.length>0)throw this.Name+':'+Err_HasDets;
    }
  r.setAttribute(szRowState,szDel);
  this.Data.removeChild(r);
  this.idx.rem(pos);
  var p=pos;
  if(pos==this.RecordCount-1&&pos>0){pos=pos-1;}else this.RecNo=this.RecNo+1;
  this.RecordCount--;
  this.DeltaChanges.add(szDel,r,null,this);
  this.idx.chg=1;this.Notify(2,p);
  this.Fields.State=null;
  this.SetPos(pos);
  this.resetdets();
  if(this.OnDelete)this.OnDelete(this);
  return 0;
  }catch(e){jcl_err(e);}
}
function QRY_modify(m)
{
  var pO,pM;
  var i,l,rs=this.Fields.State;
  pM=this.idx.row(this.RecNo);if(!pM)return -1;
  var rstate=pM.getAttribute(szRowState);
  if(rstate!=szNew){
    pO=pM.cloneNode(0);
    l=pM.childNodes.length;
    for(i=0;i<l;i++)pO.appendChild(pM.childNodes.item(i).cloneNode(0));
    if(rs!=-1)pM.setAttribute(szRowState,szMod);
	if(this.updaterow(pM,m)==-1)return -1;
    if(rs!=-1){this.DeltaChanges.add(szMod,pM,pO,this);}
  }else if(this.updaterow(pM,m)==-1)return -1;
  this.idx.chg=1;this.Fields.State=null;
  this.Notify(6,this.RecNo);
  return 0;
}
function QRY_post(m)
{
  var re;
  var rstate=this.Fields.State;
  if(rstate){
   if(this.OnBeforePost)this.OnBeforePost(this);
   if (rstate==szNew) re=this.insert(m);
   if (rstate==szMod||rstate==-1)re=this.modify(m);
   if(this.OnAfterPost)this.OnAfterPost(this);
   return re;
  }
}
function QRY_postall()
{
  var det,re=0;
  if(this.pDets){
    for(var i=0;i<this.pDets.length;i++){
	  det=this.pDets[i];
	  re=det.Post();if(re==-1){return -1;}else det.postall();
	}
  }
  return 0;
}
function QRY_cancel()
{
 this.Fields.State=null;
 if(this.MasterLink){this.MasterLink.Cancel();}
 else{
  this.AutoControl=false;
  var pos=this.RecNo;
  this.Xml.loadXML(this.oldxml);this.init();
  if (pos>this.RecordCount-1)pos=this.RecordCount-1;
  this.AutoControl=true;this.RecNo=pos;
  this.Notify(9);
  this.RecNo=-1;
  this.SetPos(pos);
 }
 var ds=this.pDets;
 if(ds)for(var i=0;i<ds.length;i++){ds[i].Notify(9);}
}
function QRY_apply()
{
  if(this.MasterLink){this.MasterLink.Apply();}
  else{
  this.Post();this.postall();
  var x,m,d;
  d=this.DeltaChanges;
  d.make();
  if(d.applyxml.documentElement.childNodes.item(2).childNodes.length==0) return -1;
  var url=this.PostUrl;
  if(!url||url=='')return -1;
  var httpob=new ActiveXObject("Microsoft.XMLHTTP");
   httpob.Open("POST",url,false);
   httpob.send(d.applyxml);
  try{
   var o=httpob.responseXML;
   var s=o.xml;
  if(!o)throw this.Name+Err_NoURL;
  if(o.parseError.errorCode!=0||!o.xml){throw this.Name+Err_NoURL+":"+httpob.responseText;}
  var msg=o.documentElement;
  if(msg.getAttribute("errorcode")!='0'){throw this.Name+':'+msg.getAttribute("message");}
   this.DeltaChanges.reset();
   this.applys();
   this.oldxml=this.Xml.xml;
   return true;
  }
 catch(e){jcl_err(e);}
 }
}
function QRY_applys()
{
 var ds=this.pDets;
 if(ds)for(var i=0;i<ds.length;i++){ds[i].applys();}
 this.oldxml=this.Xml.xml;
 this.Notify(8);
}
//new Fields(dataset);
function Fields(dataset)
{
  this.Field=new Array();
  this.Fieldx=new Array();
  this.Add=FS_addfield;
  this.Clear=function(){this.Count=0;this.Field=new Array();this.Fieldx.length=0;}
  this.Count=0;
  this.Auto=true;
  this.State;
  this.DataSet=dataset;
}
function FS_addfield(field,idx)
{
  var n=field.FieldName;
  if(n!=""){
	this.Field[n]=field;this.Fieldx[this.Count]=field;field.DataSet=this.DataSet;
	if(!idx)field.Index=this.Count;this.Count++;
  }
}
//new Field(null,null);
function Field(fieldname,node)
{
 var t,obj=document.createElement('jclfield');
 document.body.appendChild(obj);
// obj.FieldName="";//字段名称
 obj.DisplayLabel="";//字段显示名称
 obj.DisplayFormat;//格式化输出
 obj.Type="string";//字段类型
 obj.Index;//字段序号
 obj.ReadOnly=0;//是否只读
 obj.Required=0;//是否必须有值
 obj.Maxlength=0;//最大长度
 obj.Width=0;//字段宽度
 obj.SubType=null;//子类型
 obj.Decimals=null;
 obj.Fixeddec=null;
 obj.CurrencySymbol=null;
 obj.Minval=null;//最小值
 obj.Maxval=null;//最大值
 obj.Default;//默认值
 obj.Value;//字段值
 obj.OldValue;//旧值
 obj.OnChange;//字段赋值事件
 obj.Validate=FLD_validate;//效验字段值是否合法的方法
 obj.Put=FLD_putvalue;//赋值方法
 obj.Get=FLD_getvalue;//取值方法
 obj.GetValue=FLD_getfieldvalue;//取值
 obj.onpropertychange=FLD_onpropertychange;//属性变化的事件
 obj.Err;//是否有出错
 obj.Visible=true;//是否显示
 obj.DataSet;//数据
 obj.valcomp=function(v1,v2){if(v1==v2) return 0;return (v1>v2)?1:-1;}//比较值
 obj.SetValue=FLD_setvalue;//不校验赋值
 var type=typeof(node);
 if(type=='string'){
  obj.FieldKind=node.toUpperCase();
 //扩充的字段类型
  if(obj.FieldKind=='LOOKUP'){
   obj.KeyField;
   obj.LookupDataSet;
   obj.LookupKeyField;
   obj.LookupResultField;
   obj.HandleMessage=FLD_handlemessage;
  }else 
  if(obj.FieldKind=='CALC'){
  }else{obj.FieldKind='DATA';obj.Type=node.toUpperCase();}
 }
 else 
 if(type=='object'){
  obj.FieldKind='DATA';//一般的字段类型
  if(type=='object'){//一般的字段类型
   t=node.getAttribute("attrname");//取得fieldname
   obj.FieldName=t;
   t=node.getAttribute("fieldtype");//取得fieldtype
   if(t)obj.Type=t;
   obj.node=node;//字段节点
   t=node.getAttribute("width");if(t){obj.Maxlength=parseInt(t,10);obj.Width=obj.Maxlength;}
  }
 }
 if(fieldname&&fieldname!='')obj.FieldName=fieldname;
 obj.DisplayLabel=obj.FieldName;
 if(obj.Type=="INT"||obj.Type=="INTEGER"||obj.Type=="FLOAT"||obj.Type=="REAL"||obj.Type=="SHORT"||obj.Type=="BIGDECIMAL"||obj.Type=="DOUBLE"){obj.dsvalidate=xmlfloat}else
 if(obj.Type=="DATE"||obj.Type=="TIMESTAMP"){obj.dsvalidate=xmldatetime;}else
 if(obj.Type=="DATETIME"){obj.dsvalidate=xmldatetime;}
 return obj;
}
function FLD_onpropertychange()//属性(VALUE)发生变化的事件
{
  var re,n=event.propertyName;
  switch(n){
	case 'Value':
      var d=this.DataSet;
	  this.Err=null;d.Fields.Err=null;
	  if(this.OldValue!=this.Value){
       if(this.FieldKind=='DATA'){
		 try{re=this.Validate();d.Fields.Err=re;if(re)throw re;}
		 catch(e){jcl_err(e);}
	   }
	   if(!re){
		if(this.OnChange)this.OnChange(this);
		d.Notify(4,d.RecNo,this.Index);
		this.OldValue=this.Value;
		if(this.FieldKind=='DATA')if(d.OnCalcFields)d.OnCalcFields(d);
	   }
	   else {this.SetValue(this.OldValue);}
	  }
	  break;
	case 'LookupDataSet':
	  if(this.old)this.old.RemoveLink(this);
      this.LookupDataSet.LinkObj(this);
	  this.old=this.LookupDataSet;
	  break;
  }
}
function FLD_handlemessage(sender,msg,recno)
{ 
 var d=this.DataSet;
 if(d.Active==false)return;
 var fs=d.Fields;
 var f=fs.Field[this.KeyField];
 if(sender==this.LookupDataSet){
  switch(msg){
   case 3:if(f){if(fs.State!=szNew)d.Edit();f.Value=sender.Fields.Field[this.LookupKeyField].Value;}break;
   case 0:d.Notify(11);break;
   case 6:d.Notify(11);break;
  }
 }
}
function FLD_setvalue(v)
{
 this.onpropertychange=null;
 this.Value=v;this.OldValue=v;
 this.onpropertychange=FLD_onpropertychange;
}
function FLD_putvalue(r)
{
 if(this.Value!=null){r.setAttribute(this.FieldName,this.Value);}
 else r.removeAttribute(this.FieldName);
}
function FLD_getfieldvalue()
{
	var v=this.Value;
	if(v){
		if(this.DisplayFormat!=null)
		{
			if(this.Type=="INT"||this.Type=="INTEGER"||this.Type=="FLOAT"||this.Type=="REAL"||this.Type=="SHORT"||this.Type=="BIGDECIMAL"||this.Type=="DOUBLE")
			{
				v=FormatFloat(v,this.DisplayFormat);
			}
		}
	}
	return v;
}
function FLD_getvalue(r)
{
  var v;
  if(this.FieldKind=='DATA')v=r.getAttribute(this.FieldName);
  if(this.FieldKind=='LOOKUP'){
	var ld=this.LookupDataSet;
	var d=this.DataSet; 
	if(ld){
	  ld.AutoControl=false;
	  var pos=ld.RecNo;
	  ld.First();
	  var re=ld.Locate(this.LookupKeyField,d.Fields.Field[this.KeyField].Value);
      if(re==true)v=ld.Fields.Field[this.LookupResultField].Value;
	  ld.SetPos(pos);
	  ld.AutoControl=true;
	}
  }
  if(this.FieldKind=='CALC'){}
  return v;
}
function FLD_validate()
{
this.Err=null;
this.DataSet.Fields.Err=null;
var s,v=this.Value;var fn=this.FieldName;
if(this.Required&&v==""){this.Err=fn+Err_Null;}else
if(v)if(this.Maxlength&&v.length>this.Maxlength){this.Err=fn+Err_Long;}
if(this.Err){return this.Err;}
if((v!=null)&&(this.dsvalidate))s=this.dsvalidate(v);else s=v;
if(!this.Err){
 var f,mfs,dfs,fm,d=this.DataSet;var pos,dets=d.pDets;
 this.SetValue(s);
 for(var i=0;i<d.Fields.Count;i++){f=d.Fields.Fieldx[i];if(f.KeyField==this.FieldName){f.SetValue(f.Get());d.Notify(4,d.RecNo,f.Index);break;}}
 if(dets)
  for (var i=0;i<dets.length;i++)
  {
   pos=dets[i].RecNo;dets[i].AutoControl=false;
   mfs=dets[i].masterfields;
   dfs=dets[i].detailfields;
   fm=mfs.Field[fn];
   if (fm)
    for(var j=0;j<dets[i].RecordCount;j++){
     for(var k=0;k<mfs.Count;k++){
      if(fm==mfs.Fieldx[k]){
 	   f=dfs.Fieldx[k];
       if(f.Value!=s){dets[i].Fields.State=-1;dets[i].AutoControl=true;f.Value=s;}
	  }
     }
     dets[i].AutoControl=false;
 	 dets[i].Next();
    }
	dets[i].SetPos(pos);
    dets[i].AutoControl=true;
  }
}
return this.Err;
}
function xmlfloat(v)
{
  if(isNaN(v)){this.Err=this.DisplayLabel+':'+Err_Number;return null;}
  return v;
}
function xmldatetime(v)//日期时间校验
{
if(v=="") return v;
var type=typeof(v);
if(type=='object')if(this.Type=="DATETIME"||this.Type=="TIMESTAMP")v=DateTimeToStr(v);else v=DateToStr(v);
var p=v.indexOf('-');
if(p==-1){this.Err=this.DisplayLabel+':'+Err_DateTime;return null;}
return v;
}
function idx(dataset)
{
  this.dataset=dataset;
  this.chg=0;
  this.add=idxadd;
  this.rem=idxrem;//romove
  this.sort=idxsort;
  this.map=new Array();
  this.pos=idxpos;
  this.row=idxrow;
  this.fld=null;
//  this.sort(null);
}
function idxadd(e){this.map[e]=this.map.length;}
function idxpos(i){return this.map[i];}
function idxrow(i){if(i>=this.dataset.RecordCount)return null;i=this.pos(i);return (i!=null)?this.dataset.Data.childNodes.item(i):null;}
function idxrem(e){var i,l=this.map.length,v=this.map[e];for(i=e;i<l;i++) this.map[i]=this.map[i+1];this.map.length=l-1;for(i=0;i<l-1;i++)if(this.map[i]>v) this.map[i]--;}
function idxsort(name)
{
  var i,s,cnt=this.dataset.RecordCount;
  if(!cnt)cnt=0;this.map.length=cnt;
  if(this.chg==0&&name&&name==this.fld){this.map.reverse();return;}
  this.chg=0; 
  for(i=0;i<cnt;i++)this.map[i]=i;
  this.fld=name;
  if(name==null)return;
}

function DeltaChanges(dataset)
{
this.dataset=dataset;
this.action=new Array();
this.row=new Array();
this.rowOld=new Array();
this.parents=new Array();
this.rs=new Array();
this.rem=RemFromLog;
this.add=AddToLog;
this.find=FindInLog;
this.make=MakeDelta;
this.makechange=makechange;
this.remakechange=remakechange;
this.fullpath=MakePath;
this.reset=ResetLog;
}
function AddToLog(Act,pRow,pRowOld,rs)
{
if(this.dataset.ReadOnly==true){this.dataset.Cancel();jcl_err(Err_ReadOnly);return;}
var i,l=this.action.length;
if(pRowOld) for (i=0;i<l;i++) if(this.row[i]==pRow) return;
if(Act==szDel)
for(i=0;i<l;i++)
if(this.row[i]==pRow)
{
 if(this.action[i]==szNew){this.rem(i);return;}
 else{pRow=this.rowOld[i];this.rem(i);l--;break;}
}
this.action[l]=Act;
this.row[l]=pRow;
this.rowOld[l]=pRowOld;
this.parents[l]=GetParents(rs);
this.rs[l]=rs;
}
function FindInLog(r)
{
var i,l=this.action.length;
for(i=0;i<l;i++)if(this.row[i]==r) return i;
return -1;
}
function ResetLog()
{
var i,l=this.action.length;var d=this.dataset;
for(i=0;i<l;i++){this.row[i].removeAttribute(szRowState);}
this.action.length=0;this.row.length=0;this.rs.length=0;this.rowOld.length=0;
this.applyxml=null;
var dts=d.pDets;
if(dts)
 for(var i=0;i<dts.length;i++){var dt=dts[i].DeltaChanges;if(dt)dt.reset();}
}
function RemFromLog(j)
{
var i,l=this.action.length;
for(i=j;i<l-1;i++)
{
 this.action[i]=this.action[i+1];
 this.row[i]=this.row[i+1];
 this.rowOld[i]=this.rowOld[i+1];
 this.parents[i]=this.parents[i+1];
 this.rs[i]=this.rs[i+1];
}
this.action.length=l-1;
this.row.length=l-1;
this.rowOld.length=l-1;
this.parents.length=l-1;
this.rs.length=l-1;
}
function MakeDelta()
{
this.applyxml=new ActiveXObject('Microsoft.XMLDOM');a=this.applyxml;
var n = a.createProcessingInstruction("xml"," version=\"1.0\" encoding=\"gb2312\"");
a.insertBefore(n,a.firstChild);
var q=this.dataset.queryxml;
var root=q.documentElement;
var e=root.cloneNode(0);
a.appendChild(e);
var db=root.childNodes.item(0).cloneNode(1);e.appendChild(db);
var qr=root.childNodes.item(1).cloneNode(1);e.appendChild(qr);
var RD=q.createElement("ROWDATA");
e.appendChild(RD);
this.makechange(RD,szNew,szMod);
this.makechange(RD,szDel,szDel);
return a;
}

function makechange(RD,act1,act2)
{
 if(act1==szDel){this.remakechange(RD,act1,act2);}
 var l=this.action.length;
 var i,rs,pr,po;
 for(i=0;i<l;i++)
 {
  if(this.action[i]==act1||this.action[i]==act2)
  {
   rs=this.rs[i];
   pr=this.row[i].cloneNode(0);
   po=this.rowOld[i] != null ? this.rowOld[i].cloneNode(1) :null;
   if(po)
   {
    po.setAttribute(szRowState,szOrg);
    var j,f,v1,v2,cnt=0;
    for(j=0;j<rs.Fields.Count;j++)
	{
     f=rs.Fields.Fieldx[j];
     v1=f.Get(po);
     v2=f.Get(pr);
     if (f.valcomp(v1,v2)==0) pr.removeAttribute(f.FieldName);
     else cnt++;
    }
   }
   if(cnt==0){continue;}
   if(pr)pr.setAttribute(szRowState,this.action[i]);
   var j,le=this.row[i].childNodes.length;
   for(j=0;j<le;j++) pr.appendChild(this.row[i].childNodes.item(j).cloneNode(0));
   if(pr)this.fullpath(RD,po,pr,i);
  }
 }
 if(act1==szNew)this.remakechange(RD,act1,act2);
}
function remakechange(RD,act1,act2)
{
  var det,re,dets=this.dataset.pDets;
  if(dets)
    for(var i=0;i<dets.length;i++){
	  det=dets[i];
	  det.DeltaChanges.makechange(RD,act1,act2);
	}
}
function MakePath(RD,po,pr,j)
{
var pp=this.parents[j];
if(pp==null){if(po) RD.appendChild(po);RD.appendChild(pr);return;}
var i,rs=this.rs[j];
for(i=pp.length-1;i>=0;i--){
 var pM=pp[i];
 if(!pM)return;
 pM=pM.cloneNode(0);
 pM.setAttribute(szRowState,szDetUpd);
 var FldLink=rs.queryxml.createElement(rs.Name);
 if(po){FldLink.appendChild(po);po=null;}
 FldLink.appendChild(pr);
 var k,l=pp[i].childNodes.length;
 for(k=0;k<l;k++){if(pp[i].childNodes.item(k).tagName==rs.Name) pM.appendChild(FldLink);else pM.appendChild(pp[i].childNodes.item(k).cloneNode(0));}
 pr=pM;
 rs=rs.MasterLink;
}
RD.appendChild(pr);
return;
}
function GetParents(rs)
{
var p=rs.MasterLink;
if(p==null)return null;
var cnt=1,i;
var pa=new Array();
while(p.MasterLink!=null){p=p.MasterLink;cnt++;}
p=rs.MasterLink;
for(i=0;i<cnt;i++){pa[cnt-i-1]=p.idx.row(p.RecNo);p=p.MasterLink;}
return pa;
}
function findcnode(n,t)
{
if(n==null)return null;
var j,l=n.childNodes.length;
for(j=0;j<l;j++)if(n.childNodes.item(j).tagName==t)return n.childNodes.item(j);
return null;
}
new Database(null,null,null)
Database.prototype.Name;//对象名称
Database.prototype.AliasName;//别名
Database.prototype.Url;//用于JDBC的连接串
Database.prototype.Driver;//类型
function Database(name,url,driver)//数据库别名，连接信息
{
  if(name){var s='window.'+name+'=this';eval(s);}else return;
  this.Name=name;this.Url=url;this.Driver=driver;
}
