var gettop=function(p){
	var s=p||self
	var pp=s.parent
	try{var a=String(pp.document.location)}
	catch(e){return s}
	if(typeof pp.document=="unknown"){return s}
	if(pp==top){return pp}
	return gettop(pp)
};
var keys=function(id){this.id=id;this.values=[];this.link=[]},o=keys.prototype
o.setvalue=function(key,value,force,field,index,type){
if(value==null){this.deletekey(key);return}
	if((force&&typeof this.values[key]!="undefined")||(this.values[key]==null)){
		var a=this.values.length
		if(this.values[key]==null){this.link[key]=a;this.link[a]=key}
		else{a=this.link[key]}
		this.values[key]=this.values[a]=value
		if(index&&this.indexlist){this.indexlist.setvalue(key,[(field||key),index,(type||"string")],true)}
		else if(!index&&this.indexlist){this.indexlist.deletekey(key)}
	}
}

o.textreplace=function(str,d1,d2){
	var da= d1||"["
	var db= d2||"]"
	var b = this.values
	var c = this.link
	for(var i=0;i<b.length;i++){
	if(c[i]!=null&&b[i]!=null){
			str=str.replace(eval("\/\\"+da+c[i]+"\\"+db+"\/g"),b[i])
		}
	}
	return str
}
// samenvoegen van meedere waarden
o.getvalues=function(delimiter){
var a=[],b
	for(var i=1;i<arguments.length;i++){
		b = this.getvalue(arguments[i])
		if(b){a[a.length]=b}
	}
	return a.join(delimiter||" ")
}
/* 
Nieuwe argumenten
key,value,force,field,index,type,extra
> Type = veldtype (standaard string)
standaard is het veldtype string
Aangezien een databaseindex gekoppeld is aan een veldwaarde wil ik voorkomen dat index en waarde op afzonderlijke momenten worden aangemaakt of veranderd. Toevoegen van de index is optioneel. De index kan echter wel afzonderlijk worden uitgelezen. 

getvalue(key) bestaat
getfieldname(key)
getfieldvalue(key)
getfieldtype(key)

*/
// test of er ergens een key is met de waarde [value] binnen deze keyset
o.containsvalue=function(value){
	var b=this.values
	for(var i=0;i<b.length;i++){
		if(b[i]==value)return true
	}
	return false
}


// voorbeeld : productselectie.matchvalue("productnaam",["product a","product b"])
// is er in de invoerlijst [valuelist] een waarde die overeenkomt met de waarde van deze key ?
o.matchvalue=function(key,valuelist){
	if(!valuelist)return false
	var value = this.getvalue(key)
	for(var i=0;i<valuelist.length;i++){
		if(value==valuelist[i]){return true}
	}
	return false
}
// is er in de invoerlijst [valuelist] een waarde die overeenkomt met de VELD-waarde van deze key ?
// dit werkt natuurlijk alleen als de key onderdeel is van de sql-query
o.matchfieldvalue=function(key,valuelist){
	var value = this.getfieldvalue(key)
	if(!valuelist||!value)return false
	for(var i=0;i<valuelist.length;i++){
		if(value==valuelist[i]){return true}
	}
	return false
}
// NOG : is er in een andere keyset een key waarvan de waarde overeenkomt met de waarde van deze key?
// OOk : test of 2 gelijknamige keys uit verschillende keysets gelijke of afwijkende waarden hebben
// 
o.getfieldname=function(key,value){
	var n =  this.indexlist.getvalue(key)
	if(n){return (n[0]||value||null)}
	return null
}
o.getfieldvalue=function(key,value){
	var n =  this.indexlist.getvalue(key)
	if(n){return (n[1]||value||null)}
	return null
}
o.getfieldtype=function(key,value){
	var n =  this.indexlist.getvalue(key)
	if(n){return (n[2]||value||null)}
	return null
}
o.getindex=function(key,value){
	return this.indexlist.getvalue(key,value||null)
}
o.getvalue=function(key,value){
	return (this.values[key]==null)?((arguments.length==2)?value:null):this.values[key]
}
o.getkey=function(key,value){
	return (this.link[key]==null)?(value||null):this.link[key]
}
o.deletekey=function(key){
	var link=this.link[key]
	if(this.values[link]){delete this.values[link]}
	if(this.values[key]){delete this.values[key]}
	if(this.link[key]){delete this.link[key]}
	if(this.link[link]){delete this.link[link]}
	if(this.indexlist)this.indexlist.deletekey(key)
}
o.buildquerystring=function(){
	var a=[]
	var b=this.values
	var c=this.link
	for(var i=0;i<b.length;i++){
		if(c[i]!=null){a[a.length]=c[i]+"="+b[i]}
	}
	return a.join("&")
}
/* 
whereclause maakt een where-opsomming voor sql-constructie uit bestaande indexen van de variabelen
argument is AND of OR (default = AND)
voor het vaststellen van het datatype kan zonder uitlezen van de database weinig gedaan worden
Dit is belangrijk om eventuele tekstvelden in het sql-statement te quoten.

*/
o.buildwhereclause=function(how,table,quote,delimiter,wildcard){
	var a=[]
	var b=this.values
	var c=this.link
	var q = quote||"'"
	var w = wildcard||"%"
	var d = delimiter||";"
	var s = "="
	var t = table?(table+"."):""
	var index,value
	for(var i=0;i<b.length;i++){
	index = this.getindex(c[i])
		if(c[i]!=null && index){
			value = (index[2]=="string")?(s+q+index[1]+q):(index[2]=="reeks")?(" like "+q+w+d+index[1]+d+w+q):s+index[1]
			a[a.length]=t+index[0]+value
		}
	}
	return a.join(" "+(how||"and")+" ")
}
o.test=function(){
	var a=[]
	var b=this.values
	var c=this.link
	var index
	for(var i=0;i<b.length;i++){
		if(c[i]!=null){
			index = this.indexlist.getvalue(c[i])
			index = (index)?(index = " [veld:"+index[0]+" - waarde:"+index[1]+" - type:"+index[2]+"]"):""
			a[a.length]=c[i]+" : "+b[i] + index
		}
	}
	return "< "+this.id+" >\n"+a.join("\n") +"\n\n"
}

/* 
maaktabelrijen: Maak eerst een tabel met bijvoorbeeld een header met vaste breedtes
*/



o.transferto=function(targetkeyset){
	if(!targetkeyset.values)return
	var b=this.values
	for(var i=0;i<b.length;i++){
		targetkeyset.setvalue(this.getkey(i),this.getvalue(i),true)
	} 
}

// kopieeer de inhoud van de keyset naar deze keyset
o.copykeyset=function(sourcekeyset){
var s = sourcekeyset,id
	for(var i=0;i<s.link.length;i++){
	id = s.getkey(i)
		this.setvalue(
			id			,
			s.getvalue(id)		,
			true				,
			s.getfieldname(id)	,
			s.getfieldvalue(id)	,
			s.getfieldtype(id)
		)
	}
}
o.copykeysets=function(){
	for(var i=0;i<arguments.length;i++){
		this.copykeyset(arguments[i])
	}
}


// kopieer key van ene set naar andere 
o.copykey=function(sourcekeyset,key){
var s = sourcekeyset
		this.setvalue(
			key		,
			s.getvalue(key)		,
			true				,
			s.getfieldname(key)	,
			s.getfieldvalue(key),
			s.getfieldtype(key)
		)
} 

o.readquerystring=function(str,force){
	var a=unescape(String(str).replace(/\?/,"")).split("&"),b
	for(var i=0;i<a.length;i++){
		b=a[i].split("=");if(typeof b[0]!="string"||b.length==1){continue}
		this.setvalue(b[0],b[1],force)	
	}
}
o.delete_non_query_keys=function(){
	for(var i=0;i<this.values.length;i++){
	var a = this.getkey(i)
		if(!this.getfieldvalue(a)){this.deletekey(a)}
	}
}

o.deletekeys=function(){
	var a=arguments
	if(!a.length){
		this.link=[];this.values=[];this.setindexlist(true);return
	}
	for(var i=0;i<a.length;i++){
		this.deletekey(a[i])
	}
}
o.getkeynames=function(){// kopie
	return this.link.concat([])
}
o.getkeyvalues=function(){// kopie
	return this.values.concat([])
}
o.setindexlist=function(force){// kopie
	if(!this.indexlist||force)this.indexlist=new keys(this.id)
}
o=null
var getkeys=function(id,force){
	var Top = gettop() 
	if(!Top[id]||force){Top[id]=new keys(id)}
	Top[id].setindexlist()
	return Top[id]
}

/*
[*] object voor opslaan van aan groep gerelateerde indexwaarden (sql selecties)


gettop().getkeys("groepwaarden1",self,true)
getkeys('naam',self,true/false)
2e argument geeft aan waar een variabele moet worden aangemaakt die verwijst naar het object in de top
in dit geval "groepwaarden1"
true geeft aan dat een bestaande keyset in de top met dezelfde naam mag worden overschreven

deletekeys() : 
	verwijdert alle keys of..
deletekeys('key1','key2','key3')
	verwijdert key1 + key2 + key3

*/
var gettop=function(p){
	var s=p||self
	var pp=s.parent
	try{var a=String(pp.document.location)}
	catch(e){return s}
	if(typeof pp.document=="unknown"){return s}
	if(pp==top){return pp}
	return gettop(pp)
};
