function ClassBD (Pgm, WebSite, Appel) {
  this.Nom = Pgm
  this.Pgm = Pgm
  this.NomBD = "SIP"
  this.Appel = Appel
  this.WebSite = WebSite
  this.nbTable = 0
  this.Tables  = {}
	this.AddTable = AddTable

	function AddTable (Nom, Cle, Typ, ValCle, Opt) {
		var T
		T = this.Tables[Nom] = new ClassTable(Nom, Cle, Typ, ValCle, Opt)
		T.BD = this
		T.WebSite	= this.WebSite
		T.NomBD		=	this.NomBD
		this[this.nbTable] = T
		this.nbTable++
		return this.Tables[Nom]
	}
}

ClassBD.prototype.LoadJS = function(Cle, Typ, ValCle) {
	var Data, Def, T, Nom, V, D
	try {
		if (App.JSDef)  Def = JSON_Decode(App.JSDef);    //alert(JSON(Def))
		delete(App.JSDef)
	}catch(e){
		alert("Parse JSON impossible"); return
	}
	T = this.AddTable(this.Nom, Cle, Typ, ValCle);
	for (Nom in Def) {
		D = Def[Nom];  V = D.V
		switch (D.Typ) {
		  case 'D':  V = ConvDate(V);  break;
		}
			//alert(Nom+cr+V)
		T.AddChamp(Nom, Nom, D.Typ, D.Taille, V)
	}
		//delete(T.BD);  alert(JSON(T))
	return T
}

// function InitChamps(F) {   # Initialise les champs à partir du json Data
// 	var S, V, Ch, T
// 	InitSelects()
// 	F = LID(F);  T = BD.Table
// 	for (Nom in T.Data) {
// 		V = T.Data[Nom];    //alert(Nom+cr+V)
// 		switch (T.Def[Nom].Typ) {
// 		  case 'D':  V = ConvDate(V);  break;
// 		}
// 		if (F)  Ch = F.elements[Nom];  else  Ch = LID(Nom)
// 		PVal(Nom,V)
// 	}
// }

function ClassTable (Nom, Cle, Typ, ValCle, Opt) {
	if (ValCle=='null')  ValCle=null
  this.Nom			= Nom
  this.NomTable	= Nom
  this.NomCle		= Cle
  this.TypCle		= Typ
  this.ValCle		= ValCle
  this.Form     = null
	this.nbChamp	= 0
	this.nbChMaj  = 0
  this.Champs		= {}
  this.Data			= null
  AddProperty (this, Opt)
}

ClassTable.prototype.AddChamp = function (Nom, Lib, Typ, Taille, V, Opt) {
	this.Champs[Nom] = new ClassChamp(this, Nom, Lib, Typ, Taille, V, Opt)
	this[this.nbChamp] = this.Champs[Nom]
	this.nbChamp++
	return this.Champs[Nom]
}

ClassTable.prototype.Init = function () {
	var i, Ch, V
	if (!this.Form)  this.Form = LID('Form')
	for (i=0; i<this.nbChamp; i++) {
		Ch = this[i]
		V = Ch.V
		switch (Ch.Typ) {
			case "T":
			case "M":  if (V)  Ch.V = Replace(V,"<xx>","\r\n");  break
		}
		//alert(V + crr + unescape(V))
	}
}

ClassTable.prototype.InitChamps = function(Suffix) {
	var i, Ch, Ctl, V, Nom, S
	for (i=0; i<this.nbChamp; i++) {
		Ch = this[i]
		Nom = Ch.Nom;  if (Suffix)  Nom+=Suffix;		//alert(Ch.Nom + crr + Ch.Typ + crr + Ch.Taille + crr + Lout(LID(Nom)))
		if (this.Form)  Ctl = this.Form.elements[Nom];  else  Ctl = LID(Nom);  if (!Ctl)  continue;
		Ch.Ctl = Ctl
		Ctl.onchange=Change
		if (Ch.Typ=="T" && Ctl.type && Ctl.type=="text" && Ch.Taille)  Ctl.maxLength = Ch.Taille  // && LX(Ctl,"maxLength")>999
		SetAt(Ctl,"Table=" + Ch.Table.Nom + ";Typ=" + Ch.Typ)
		V = Ch.V
		//if (Ch.Typ=="M" && !V)  V = LVal(this.Form.elements[this.Nom+"_"+Ch.Nom])
		if (Ch.Typ=='M' && !V)  V = LVal(this.Nom+"_"+Ch.Nom)
    PX(Ctl,'bd','o')
      //if (Nom=='Descript')  alert(Nom+cr+V+'.'+crr+Lout(Ctl))
		if (V) {
			PVal(Ctl,V);
		}else if ((S=LX(Ctl,"Valeur"))) {
		  if (S.substr(0,1)=="=")  S = Eval(S.substr(1));  else  V = S
			PVal(Ctl,S)
		}else if (!this.ValCle && (S=LX(Ctl,"ValDef"))) {
		  if (S.substr(0,1)=="=")  S = Eval(S.substr(1));  else  V = S
			PVal(Ctl,S)
		}else if (this.PlusieursForm) {
			PVal(Ctl,'');
		}
	}
}

ClassTable.prototype.CalcChange = function(CtlChange) {
	var i, Ch, V, Val, Nom, Ctl, Li="", L2="", Ok
	for (i=0; i<this.nbChamp; i++) {
		Ch = this[i];  Ctl = Ch.Ctl;  Ok = false;  if (!Ctl) continue
		Nom=Ch.Nom
		V=Ch.V
		if (Ch.Typ=="M" && !V)  V = LVal(this.Nom+"_"+Ch.Nom)

		if (Ctl.type && Ctl.type=="checkbox")
			Ok = (Ctl.checked!=(V?true:false))
		else{
		  Val = Ctl.value
		  if (V==null) {
			  if (Val!="" && Val!=0)  Ok = true
			}else
				Ok = (Val!=V)
		}
		if (Ok) {
		  Ch.Maj = 1
			Li += Ch.Nom + ";";
			L2 += Nom + ", V=" + V + ", val=" + Ctl.value + "\n"
		}else
		  Ch.Maj = 0
		//if (Ch.Typ=="D") alert("CalcChange\nOk=" + Ok+", " + Nom+", "+Ch.Typ+crr+ V+", Val="+Val + crr + Ctl.value + "," + crr + Lout(Ctl))
	}
	if (CtlChange)  CtlChange.value = Val = ";" + Li;  //alert(Li + crr + L2)
	if (!Val)  return

	// ajouter les codes
	for (i=0; i<this.nbChamp; i++) {
		Ch = this[i];  Ctl = Ch.Ctl;  if (!Ctl || !Ch.V) continue;  if (!LX(Ctl,"ChampMaj"))  continue;
		Nom = Ch.Nom
		if (CtlChange && Val.indexOf(";"+Nom+";")<0)  CtlChange.value = Val + Nom + ";"
	}
}

ClassTable.prototype.ListChange = function(For) {   // retourne la chaine des modifs + variables obligs. Les obligs sont : ctl avec nom = '_*' ou ChampMaj=o
	var i, Ch, Li='', La='', S, Nom
	if (!For)  For=''
	if (For!='suppr')  this.ChampsMaj()
	for (i=0; i<this.nbChamp; i++) {
		Ch = this[i];
		S = '&' + Ch.Nom + '='+ escape(Ch.Val())
		if (Ch.Maj)
			Li += S   //encodeURI(LVal(Ctl))
		else if (Ch.Nom==this.NomCle)
			La += S
	}
	if (!Li && For!='suppr')  return Li
	Li+=La
	if (!(F=this.Form))  return Li
  for (i=0; i<F.elements.length; i++) {
		Ctl = F.elements[i];  //alert(Ctl.outerHTML)
		Nom = Ctl.name
		if ((Nom.substr(0,1)=='_' || LX(Ctl,'ChampMaj')) && Li.indexOf('&'+Nom+'=')<0)  Li += '&' + Ctl.name + '=' + escape(LVal(Ctl))   //escape(encodeURI(LVal(Ctl)))
  }
	return Li;
}

ClassTable.prototype.ChampsMaj = function() {
  // inscrit les champs modifiés. ChampMaj=o doit être inclu dans INPUT pour les champs qui ne font pas partie de la table chargée et ne comment pas par _, ou ne sont pas modifiés mais doit qd même être inclus
	var i, Ch, V, Val, Nom, Ctl, Li="", L2="", Ok
	for (i=0; i<this.nbChamp; i++) {
		Ch = this[i];  Ctl = Ch.Ctl;  Ok = false;  if (!Ctl) continue
		Nom=Ch.Nom
		V=Ch.V
		if (Ch.Typ=="M" && !V)  V = LVal(this.Nom+"_"+Ch.Nom)

		if (Ctl.type && Ctl.type=="checkbox")
			Ok = (Ctl.checked!=(V?true:false))
		else{
			Val = Ctl.value
			if (V==null) {
				if (Val!="" && Val!=0)  Ok = true
			}else
				Ok = (Val!=V)
		}
		if (Ok) {
			Ch.Maj = 1
		}else
			Ch.Maj = 0
	}
}



function ClassChamp (Table, Nom, Lib, Typ, Taille, Valeur, Opt) {
	var S, V
	this.Table  = Table
	this.Nom    = Nom
	this.Typ    = Typ
	this.Taille = Taille;  //if (V==undefined)  V=""
	this.Maj		= 0
	if (Lib)  this.Lib = Lib;  else  this.Lib = Nom
	if (Valeur==undefined)
		V = null
	else
		switch(Typ) {
			case "T": case "M":  V = unescape(Valeur);  break
			case "B": if (typeof(Valeur)=="string")  V = eval(Valeur.toLowerCase());  else  V = Valeur;  break
			default:	V = Valeur
		}
	this.V = V
	this.oldV = V
	this.Ctl = null
	AddProperty (this, Opt)
}

ClassChamp.prototype.Val = function(Valeur) {
	if (Valeur==undefined) {
		//return this.V
		if (this.Ctl)  return LVal(this.Ctl);  else  return this.V
	}
	this.Val = Valeur
	if (this.Ctl)  this.Ctl.value = Valeur
}



