//<% 
//remove '//' from '//<%' above, for server side ASP, see also bottom of page to remove other '//'. When removed rename to database.inc and use include file on ASP to pull page.
/*
AccessObject-JavaScriptDatabase (v3.20)
Latest Version and help file available at http://www.javascriptdatabase.com. Also, demos/downloads, forum. And 
freeware Microsoft Visual Basic Module for Microsoft Access that can generate javascript recordsets and records.

Copyright (C) 2000 Kevin Gibney
Distributed under the terms of the GNU Library General Public License
*/


//start universal variables
var ajdbd = 2  //debug depth for AOJS debug messages
var dbIndex=1
var dbTypeBoolean = 240
var dbTypeCurrency = 260
var dbTypeDate = 250
var dbTypeInteger = 220
var dbTypeReal = 230
var dbTypeText = 210
//end universal variables
//***START DATABASE DEFINITION***
	//**Database Object
function Database(name) {
	//Database Properties
	this.DBaseProperties = new DatabaseProperties()
	this.DBaseProperties.Name = name
	
	//Database CookieProperties
	this.DBaseCookieProperties = new CookieProperties()
	
	//Recordsets Collection	
	this.Recordsets=new Function('index','return this.Recordsets.Item(index)')
	this.Recordsets.object_list = new Object()	
	this.Recordsets.array_list = new Array()
	this.Recordsets.Count = 0
	this.Recordsets.Item = _collection_item
	this.Recordsets.Add = _collection_add
	this.Recordsets.Delete = _collection_delete
}
	//**Database Methods
	Database.prototype.CreateRecordset = _create_recordset
	Database.prototype.DeleteRecordset = _delete_recordset //not tested
	Database.prototype.ResetRecordset = _reset_recordset

	//**Database Properties
function DatabaseProperties() {
	//this.Name
	this.AOJDVersion="3.2"
	this.AOJDLastUpdated="19/12/2000"
	this.CreateCookieRecordset = true
}
//***END DATABASE DEFINITION***


//***START RECORDSET DEFINITION***
	//**Recordset Object
function Recordset() {
	//Recordset Properties
	this.RsetProperties = new RecordsetProperties()
	
	//Record Arrays
	this.RsetRecs = new Array()		
	this.DeletedRecs = new Array()
	
	//Fields Collection
	this.Fields=new Function('index','return this.Fields.Item(index)')
	this.Fields.object_list = new Object()	
	this.Fields.array_list = new Array()
	this.Fields.Count = 0
	this.Fields.Item = _collection_item
	this.Fields.Add = _collection_add

	//Indexed Collection
	this.Indexed=new Function('index','return this.Indexed.Item(index)')
	this.Indexed.object_list = new Object()	
	this.Indexed.array_list = new Array()
	this.Indexed.Count = 0
	this.Indexed.Item = _collection_item
	this.Indexed.Add = _collection_add
}
	//**Recordset Methods
	Recordset.prototype.A = _add_rec
	Recordset.prototype.AddRec = _add_rec
	Recordset.prototype.AddIndexed = _add_indexed
	Recordset.prototype.BOF = _bof
	Recordset.prototype.CreateField = _create_field
	Recordset.prototype.ChangeQuery = _change_query
	Recordset.prototype.Count = _count
	Recordset.prototype.CompareRows = _compare_rows
	Recordset.prototype.DeleteRec = _delete_rec
	Recordset.prototype.DumpRecordset= _dump_recordset
	Recordset.prototype.EOF = _eof
	Recordset.prototype.FindFirst = _find_first
	Recordset.prototype.FindLast = _find_last
	Recordset.prototype.FindNext = _find_next
	Recordset.prototype.FindPrevious = _find_previous
	Recordset.prototype.Find = _find
	Recordset.prototype.GetPageArray = _get_page_array
	Recordset.prototype.MoveFirst = _move_first
	Recordset.prototype.MoveLast = _move_last
	Recordset.prototype.MoveNext = _move_next
	Recordset.prototype.MovePrevious = _move_previous
	Recordset.prototype.RecDeleted = _recdeleted
	Recordset.prototype.ResetIndexed = _reset_indexed
	Recordset.prototype.SetCurrentFields = _set_current_fields
	Recordset.prototype.Sort = _sort
	Recordset.prototype.Seek = _seek
	Recordset.prototype.UpdateField = _update_field
	
	//**Recordset Properties
function RecordsetProperties() {
	this.BadQuery=false
	this.Bof=false
	this.CookieOn = false
	this.CurrentRecord=-1
	this.CurrentQuery=""
	this.CurrentQueryChanged=""
	this.Eof=false
	this.Name=""
	this.NoMatch=false
	this.OrdinalPosition=-1
	//this.MyDatabase
	this.RecsDeleted=0
	this.RecsUndeleted=0
}

	//**Field Properties
function FieldProperties() {
	this.Indexed = false
	this.IndexedField = new Object()
	this.Name = ""
	this.OrdinalPosition = -1
	this.Type = ""
	this.Value = ""
}
//***END RECORDSET DEFINITION***


//***Methods and functions***
//**Start Create methods
function _create_recordset(name,options) {
	if ((typeof(this[name])=="undefined" || this[name]==null) && (typeof(name)!="undefined")) {
		this[name]=new Recordset()
		this[name].RsetProperties.MyDatabase=this
		this[name].RsetProperties.Name=name
		this[name].RsetProperties.OrdinalPosition=this.Recordsets.array_list.length
		this.Recordsets.Add(this[name],name)
		return true
	} else {
		//if (this.DBaseCookieProperties.Loaded != true) alert('Error:\n\nYou are either \n1)Trying to create a recordset that already exists\n2)The recordset name clashes with an internal database property\n3)You are trying to create a recordset with no name(undefined).\n\nrecordset name='+name)
		return false
	}
}
function _delete_recordset(name) {
	//not tested
	this.Recordsets.Delete(this[name])
}
function _reset_recordset(name) {
	this.Recordsets(name).RsetRecs = new Array()		
	this.Recordsets(name).DeletedRecs = new Array()
	with (this.Recordsets(name).RsetProperties) {
		BadQuery=false
		Bof=false
		CookieOn = false
		CurrentRecord=-1
		CurrentQuery=""
		CurrentQueryChanged=""
		Eof=false
		//Name=""
		NoMatch=false
		//OrdinalPosition=-1
		//MyDatabase
		RecsDeleted=0
		RecsUndeleted=0
	}
	//------- RLC change --------
	if (this.Recordsets(name).Indexed.Count != 0)
	  {this.Recordsets(name).Indexed.array_list[0].FieldProperties.IndexedField = new Object()}
	//--------------------------------------
}

function _create_field(fieldname,type) {
	if ((typeof(this[fieldname])=="undefined") && (typeof(fieldname)!="undefined")) {
		this[fieldname] = new Object()
		this[fieldname].FieldProperties = new FieldProperties()
		this[fieldname].FieldProperties.Name = fieldname
		this[fieldname].FieldProperties.OrdinalPosition=this.Fields.array_list.length
		if (typeof(type)!="undefined") this[fieldname].FieldProperties.Type = type
		this.Fields.Add(this[fieldname],fieldname)
		if (type==dbIndex) {
			this.Indexed.Add(this[fieldname],fieldname)
			this[fieldname].FieldProperties.Indexed = true
		}
		return true
	}
	else {
		if (this.RsetProperties.MyDatabase.DBaseCookieProperties.Loaded != true) alert('Error:\n\nYou are either \n1)Trying to create a field that already exists\n2)The fieldname clashes with an internal database property\n3)You are trying to create a field with no name(undefined).\n\nfieldname='+fieldname)
		return false
	}
}
//**End Create Methods


//**Start Collection Methods
function _collection_add(item,key) {
	this.object_list[key]=item
	var pos=this.array_list.length
	this.array_list[pos]=item
	this.Count++
}
function _collection_delete(item) {
	var new_object_list = new Object()
	var new_array_list = new Array()
	for (prop in this.object_list) {
		if (this.object_list[prop] != item) {
			new_object_list[prop] = this.object_list[prop]
			new_array_list[new_array_list.length]=item
		} else {
			item=null
		}
	}
	this.object_list = new_object_list
	this.array_list = new_array_list
}
function _collection_item(index) {
	if (this.Count == 0) {
		return false		
	}
	switch (typeof(index)) {
		case "undefined":
			return false
		case "number":
			if (index>this.array_list.length-1) return false
			return this.array_list[index]
		case "string":
			if (typeof(this.object_list[index])=="undefined") return false
			return this.object_list[index]
	}
}
//**End Collection Methods


function _set_current_fields() {
	if (this.RsetProperties.RecsUndeleted==0) return false
	for (var fidx=0;fidx<this.Fields.Count;fidx++) {
		this[this.Fields(fidx).FieldProperties.Name]=this.RsetRecs[this.RsetProperties.CurrentRecord][fidx]
		this.Fields(fidx).FieldProperties.Value=this.RsetRecs[this.RsetProperties.CurrentRecord][fidx]
	}
}

function _add_rec(fields) 
{
	var ridx = this.RsetRecs.length	
	this.DeletedRecs[ridx] = false
	this.RsetProperties.RecsUndeleted++
	this.RsetRecs[ridx] = fields //set record
	
	//create reverse index
	if (this.Indexed.Count==1) 
	{
		var idxfield = this.Indexed.array_list[0].FieldProperties
		idxfield.IndexedField[fields[idxfield.OrdinalPosition]]=ridx
	} else 
	{
		for (var idx=0;idx<this.Indexed.Count;idx++) 
		{
//BUG??	 
//var idxfield = this.Indexed.array_list[0].FieldProperties
// RLC change:		
			var idxfield = this.Indexed.array_list[idx].FieldProperties
// end RLC change

			idxfield.IndexedField[fields[idxfield.OrdinalPosition]]=ridx
		}
	}

}

function _delete_rec() {
	//check for valid field
	if (this.RsetProperties.RecsUndeleted==0) return false
	this.DeletedRecs[this.RsetProperties.CurrentRecord]=true
	this.RsetProperties.RecsDeleted++
	this.RsetProperties.RecsUndeleted--
	this.SetCurrentFields()

}

function _recdeleted() {
	return(this.DeletedRecs[this.RsetProperties.CurrentRecord])
}

function _update_field(field,newvalue) {
	if (this.Fields(field) == false) {
		alert('Cannot update field, field not created for this recordset: ' + field)
		return false
	}
	if (this.Fields(field).FieldProperties.Indexed==true) {
		alert('Error:\n\nYou cannot update an Indexed field.\n\nField='+field)
		return false
	}
	this.RsetRecs[this.RsetProperties.CurrentRecord][this.Fields(field).FieldProperties.OrdinalPosition] = newvalue
	this.SetCurrentFields()


	return true
}

//Start Seek releated methods
function _reset_indexed() {
	for (var fidx=0;fidx<this.Fields.Count;fidx++) {
		if (this.Fields(fidx).FieldProperties.Indexed==true) {
			for (var ridx=0;ridx<this.RsetRecs.length;ridx++) {
				this.AddIndexed(fidx,this.RsetRecs[ridx][fidx],ridx)
			}
		}
	}
}

function _add_indexed(fidx,fvalue,ridx) {
	this.Fields(fidx).FieldProperties.IndexedField[fvalue]=ridx
}

function _seek(var1,var2) {
	if  (arguments.length==1) {
		field = this.Indexed(0).FieldProperties.Name+""		
		indexed = var1
	} else {
		field = var1
		indexed = var2
	}
	
	if (typeof(this.Fields(field).FieldProperties.IndexedField[indexed])!="undefined") {
		if (this.DeletedRecs[this.Fields(field).FieldProperties.IndexedField[indexed]]) return false
		this.RsetProperties.CurrentRecord=this.Fields(field).FieldProperties.IndexedField[indexed]	
		this.RsetProperties.NoMatch = false
		this.SetCurrentFields()
		return true
	} else {
		this.RsetProperties.NoMatch = true
		return false
	}
}
//End Seek releated methods

function _eof() {
	if (this.RsetProperties.CurrentRecord < this.RsetRecs.length) {
		this.RsetProperties.Eof=false
		this.RsetProperties.Bof=false
		return false
	}
	this.RsetProperties.Eof=true
	this.RsetProperties.CurrentRecord=this.RsetRecs.length
	return true	
}

function _bof() {
	if (this.RsetProperties.CurrentRecord > -1) {
		this.RsetProperties.Bof=false
		this.RsetProperties.Eof=false
		return false
	}
	this.RsetProperties.Bof=true
	this.RsetProperties.CurrentRecord=-1
	return true
}



//**Start Move methods
function _move_next() {
 	this.RsetProperties.CurrentRecord++
	while (this.RecDeleted() && (!this.EOF())) {
		this.RsetProperties.CurrentRecord++
	}
	if (!this.EOF()) this.SetCurrentFields()
}

function _move_previous() {
 	this.RsetProperties.CurrentRecord--
	while (this.RecDeleted() && (!this.BOF())) {
		this.RsetProperties.CurrentRecord--
	}
	if (!this.BOF()) this.SetCurrentFields() 
}

function _move_first() {
	this.RsetProperties.CurrentRecord = 0
	while (this.RecDeleted() && (!this.EOF())) {
		this.RsetProperties.CurrentRecord++
	}	
	if ((this.BOF() == false) && (this.EOF() == false)) this.SetCurrentFields()
}

function _move_last() {
	this.RsetProperties.CurrentRecord = this.RsetRecs.length-1
	while (this.RecDeleted() && (!this.BOF())) {
		this.RsetProperties.CurrentRecord--
	}	
	if ((this.BOF() == false) && (this.EOF() == false)) this.SetCurrentFields()
}
//**End Move methods



//**Start Find methods
function _find_first(query) {	
	var temp=this.RsetProperties.CurrentRecord
	this.RsetProperties.CurrentRecord=0
	if (!this.EOF()) {
		this.Find("forward",query)
		if (this.RsetProperties.NoMatch) {	
			this.RsetProperties.CurrentRecord=temp
			this.EOF()
			this.BOF()
		}		
	} else {
		this.RsetProperties.NoMatch=true
		this.RsetProperties.CurrentRecord=temp
		this.EOF()
		this.BOF()
	}
	this.SetCurrentFields()
}

function _find_next(query) {
	var temp=this.RsetProperties.CurrentRecord
	this.RsetProperties.CurrentRecord++
	if (!this.EOF()) {
		this.Find("forward",query)
		if (this.RsetProperties.NoMatch) {	
			this.RsetProperties.CurrentRecord=temp
			this.EOF()
			this.BOF()
		}		
	} else {
		this.RsetProperties.NoMatch=true
		this.RsetProperties.CurrentRecord=temp
		this.EOF()
		this.BOF()
	}
	this.SetCurrentFields()
}

function _find_last(query) {
	var temp=this.RsetProperties.CurrentRecord
	this.RsetProperties.CurrentRecord=this.RsetRecs.length-1
	if (!this.BOF()) {
		this.Find("backward",query)
		if (this.RsetProperties.NoMatch) {	
			this.RsetProperties.CurrentRecord=temp
			this.EOF()
			this.BOF()	
		}		
	} else {
		this.RsetProperties.NoMatch=true
		this.RsetProperties.CurrentRecord=temp
		this.EOF()
		this.BOF()
	}
	this.SetCurrentFields()
}

function _find_previous(query) {
	var temp=this.RsetProperties.CurrentRecord
	this.RsetProperties.CurrentRecord--
	if (!this.BOF()) {
		this.Find("backward",query)
		if (this.RsetProperties.NoMatch) {	
			this.RsetProperties.CurrentRecord=temp
			this.EOF()
			this.BOF()
		}		
	} else {
		this.RsetProperties.NoMatch=true
		this.RsetProperties.CurrentRecord=temp
		this.EOF()
		this.BOF()
	}
	this.SetCurrentFields()
}

function _find(direction, query) {
	this.RsetProperties.NoMatch = true
	if (this.RsetProperties.CurrentQuery!=query) {
		var new_query=this.ChangeQuery(query) + ""
		if (this.RsetProperties.BadQuery) return -1
	} else {
		new_query=this.RsetProperties.CurrentQueryChanged
	}

	var ridx = this.RsetProperties.CurrentRecord
	if (direction=="forward") {
		for (ridx;ridx<this.RsetRecs.length;ridx++) {
			if ((!this.DeletedRecs[ridx]) && (eval(new_query))) {	
				this.RsetProperties.CurrentRecord=ridx
				this.RsetProperties.NoMatch = false
				break
			}
		}
	} else {
		for (ridx;ridx>-1;ridx--) {
			if ((!this.DeletedRecs[ridx]) && (eval(new_query))) {
				this.RsetProperties.CurrentRecord=ridx
				this.RsetProperties.NoMatch=false
				break
			}
		}
	} 							
}
//**End Find Methods

function _change_query(query) {
	this.RsetProperties.CurrentQuery=query
	this.RsetProperties.BadQuery=true
	var new_query = query
	for (var fidx=0;fidx<this.Fields.Count;fidx++) {
		if (query.indexOf(this.Fields(fidx).FieldProperties.Name) != -1) {
			this.RsetProperties.BadQuery=false
			var replace_string = "this.RsetRecs[ridx][" + fidx + "]"
			query=new_query
			new_query = query.replace(eval("/" + this.Fields(fidx).FieldProperties.Name + "/g"),replace_string)
		}
	} 

	this.RsetProperties.CurrentQueryChanged=new_query	
	return new_query
}

function _get_page_array(pageSize,query) {
	var countRec=0
	var count=0
	var recID=new Array()
	var fidx=this.Indexed(0).FieldProperties.OrdinalPosition

	this.RsetProperties.NoMatch = true
	if (this.RsetProperties.CurrentQuery!=query) {
		var new_query=this.ChangeQuery(query) + ""
		if (this.RsetProperties.BadQuery) return -1
	} else {
		new_query=this.RsetProperties.CurrentQueryChanged
	}

	for (var ridx=0;ridx<this.RsetRecs.length;ridx++) {
		if ((!this.DeletedRecs[ridx]) && (eval(new_query))) {	
			if (countRec==0) {
				recID[recID.length]=this.RsetRecs[ridx][fidx]
			} 
			if (countRec==pageSize-1)	{
				countRec=-1
			}
			countRec++
			count++
		}
	}
	this.RsetProperties.NoMatch=false		
	recID.Count=count
	return recID
}


//begin Sort methods
function _sort(fields,orders) {
	var orderserror=false
	if (typeof(fields) == "undefined") { 
		alert('Error:\n\nYou are are tring to use Sort() method without passing any fields')
		return false
	}
	_sort.fields = fields.split(",")
	for (var fidx=0;fidx<_sort.fields.length;fidx++) {
		var tempfieldname=_sort.fields[fidx]
		_sort.fields[fidx]=this.Fields(tempfieldname).FieldProperties.OrdinalPosition
	}
	
	if (typeof(orders) != "undefined") {
		_sort.orders = orders.split(",")
		if (_sort.orders.length != _sort.fields.length) {
			alert('Error:\n\nNumber of Sort order fields must match number of Order fields')
			return
		}
		for (var i=0;i<_sort.orders.length;i++) (_sort.orders[i]=="ascend")?_sort.orders[i]=true:(_sort.orders[i]=="descend")?_sort.orders[i]=false:orderserror=true;
		if (orderserror==true) {
			alert('Error:\n\nBad order value in Sort method')
			return
		}
	}
	else {
		_sort.orders = new Array()
		for (var i=0;i<_sort.fields.length;i++) _sort.orders[i]=true
	}
	eval(this.RsetRecs.sort(this.CompareRows))
	this.ResetIndexed()
}

function _compare_rows(X,Y) {	
	with (_sort) {
		for (var r=0;r<fields.length;r++) {
			var f = fields[r]
			if(X[f]<Y[f]) return orders[r]?-1:1;
			if(Y[f]<X[f]) return orders[r]?1:-1;
		}
		return 0
	}
}
//end Sort methods

function _count(query) {
	if ((typeof(query) == "undefined") || query == "") {
		this.RsetProperties.NoMatch=false
		return this.RsetProperties.RecsUndeleted		
	}	

	count=0
	
	if (this.RsetProperties.CurrentQuery!=query) {
		var new_query=this.ChangeQuery(query) + ""
		if (this.RsetProperties.BadQuery) return -1
	} else {
		new_query=this.RsetProperties.CurrentQueryChanged
	}
	
	for (var ridx=0;ridx<this.RsetRecs.length;ridx++) {
		if ((!this.DeletedRecs[ridx]) && eval(new_query)) {	
			count++
		}
	}
	(count==0)?this.RsetProperties.NoMatch=true:this.RsetProperties.NoMatch=false
	return count
}

function _dump_recordset(fn,fd,rd) {
	//fn = field name array, fd = field delimitor, rd = record delimitor
	var nofRecs = this.Count()
	if (nofRecs == 0) return "no recs"
	
	var s='',count=0
	this.MoveFirst()
	while (!this.RsetProperties.Eof) {
		count++
		for (var f=0;f<fn.length;f++) {
			if (f != 0) s+= fd
			s += this[fn[f]]
		}
		if (count<nofRecs) s += rd
		
		this.MoveNext()
	}

	return s
}


/*
CookieMethods(v1) for Access-Object JavaScript Database
Latest Version and help file available at http://www.javascriptdatabase.com

Copyright (C) 2000 Kevin Gibney
Distributed under the terms of the GNU Library General Public License
*/
function CookieProperties() {
	//these properties are fields in DBaseCookieRecordset.
	this.Domain = ''		//rw	string
	//this.Expires			//r		string
	this.ExpireHours = 0 	//rw 	integer 	1 = 1 hour
	this.ExpireMinutes = 0  //rw	integer 	1 = 1 min
	this.Path = ''			//rw	string
	this.Secure = false		//rw	boolean
	
	//other
	this.Document = ''		//r		string		set to current 'document'(object) client side and string server side ASP
	
	//extra properties that can be viewed after saving cookie
	this.CookieString = ''	//r		string		unescaped
	this.CookieLength = 0	//r		integer		
	this.Loaded = false		//r		boolean

	//all rw strings
	this.SeparatorDBName = '=' 				
	this.SeparatorFieldNames = ','
	this.SeparatorFielddbIndex = ','
	this.SeparatorFieldType = ','
	this.SeparatorFieldValues = '#'			//field value separator
	this.SeparatorRecords = '*'				//records separator
	this.SeparatorRsets = '*RSETS*'			//RecordSETs Separator
	this.SeparatorRsetDefinition = '*RD*' 	//Recordset Definition Separatot
	this.SeparatorEnd = ';'
}

function _cookie_save(){
	if (this.Recordsets.Count > 0) {
		//create and load cookie recordset
		if ((this.DBaseProperties.CreateCookieRecordset == true) && (typeof(this.DBaseCookieRecordset) != "undefined")) {
			this.LoadCookieRecordset()
		}
		
		if (typeof(document)=="undefined") {
			//ASP
			//Note: date.toGMTString() function does not seem to work in my version of win2000 server side - hence the hack
			var expiretime = 0
			if (this.DBaseCookieProperties.ExpireHours != 0)  expiretime=this.DBaseCookieProperties.ExpireHours*(1000*60*60)
			if (this.DBaseCookieProperties.ExpireMinutes != 0)  expiretime+=this.DBaseCookieProperties.ExpireMinutes*(1000*60)
	
			if (expiretime != 0) this.DBaseCookieProperties.Expires = new Date((new Date()).getTime() + expiretime)

			var myyear = this.DBaseCookieProperties.Expires.getFullYear()
			var mymonth = this.DBaseCookieProperties.Expires.getMonth() + 1
			var myday = this.DBaseCookieProperties.Expires.getDate()
			
			var myHH = this.DBaseCookieProperties.Expires.getHours()
			var myMM = this.DBaseCookieProperties.Expires.getMinutes()
			var mySS = this.DBaseCookieProperties.Expires.getSeconds()
			var expireon = myday + "-" + mymonth + "-" + myyear + " " + myHH + ":" + myMM + ":" + mySS

			//.toGMTString()does not work
		} else {
			//Client side			
			var expiretime = 0
			if (this.DBaseCookieProperties.ExpireHours != 0)  expiretime=this.DBaseCookieProperties.ExpireHours*(1000*60*60)
			if (this.DBaseCookieProperties.ExpireMinutes != 0)  expiretime+=this.DBaseCookieProperties.ExpireMinutes*(1000*60)
	
			if (expiretime != 0) this.DBaseCookieProperties.Expires = new Date((new Date()).getTime() + expiretime)
			var cookieExtras = ""
			
			//.toGMTString is required for client side NOT server side (it doesnt work - error)
			if (expiretime != 0) cookieExtras += '; expires=' + this.DBaseCookieProperties.Expires.toUTCString()
			if (this.DBaseCookieProperties.Path != '') cookieExtras += '; path=' + this.DBaseCookieProperties.Path
			if (this.DBaseCookieProperties.Domain != '') cookieExtras += '; domain=' + this.DBaseCookieProperties.Domain
			if (this.DBaseCookieProperties.Secure != false) cookieExtras += '; secure'
		}

		with (this.DBaseCookieRecordset) {
			MoveFirst()
			UpdateField('Expires',this.DBaseCookieProperties.Expires.toUTCString())
		}
		
		var s = ''
		var startRsetLoop = true
		for (var r=0;r<this.Recordsets.Count;r++) {
			if (this.Recordsets(r).RsetProperties.CookieOn) {
				//recordsets separator
				if (!startRsetLoop) s+= this.DBaseCookieProperties.SeparatorRsets
				startRsetLoop = false
				
				//recordset name
				s += this.Recordsets(r).RsetProperties.Name + this.DBaseCookieProperties.SeparatorRsetDefinition
				
				//fieldproperties: Name,Indexed,Type
				var sFN="",sFI="",sFT=""
				if (this.Recordsets(r).Fields.Count>0) {	
					sFN = this.Recordsets(r).Fields(0).FieldProperties.Name
					sFI = this.Recordsets(r).Fields(0).FieldProperties.Indexed
					sFT = this.Recordsets(r).Fields(0).FieldProperties.Type
				}
				for (var f=1;f<this.Recordsets(r).Fields.Count;f++) {
					sFN += this.DBaseCookieProperties.SeparatorFieldNames + this.Recordsets(r).Fields(f).FieldProperties.Name
					sFI += this.DBaseCookieProperties.SeparatorFielddbIndex + this.Recordsets(r).Fields(f).FieldProperties.Indexed
					sFT += this.DBaseCookieProperties.SeparatorFieldType + this.Recordsets(r).Fields(f).FieldProperties.Type
				}
				s += sFN + this.DBaseCookieProperties.SeparatorRsetDefinition
				s += sFI + this.DBaseCookieProperties.SeparatorRsetDefinition
				s += sFT + this.DBaseCookieProperties.SeparatorRsetDefinition
				
				//save recordset records
				var sR = ""
				if (this.Recordsets(r).Count() > 0) {
					var startRecordLoop = true, currentrec
					this.Recordsets(r).MoveFirst()
					while (!this.Recordsets(r).RsetProperties.Eof) {
						currentrec=this.Recordsets(r).RsetProperties.CurrentRecord
						if (this.Recordsets(r).DeletedRecs[currentrec]==false) {
							if (!startRecordLoop) sR += this.DBaseCookieProperties.SeparatorRecords
							sR += this.Recordsets(r).RsetRecs[currentrec].join(this.DBaseCookieProperties.SeparatorFieldValues)
							startRecordLoop = false
						}
						this.Recordsets(r).MoveNext()
						
					}
					s += sR
				}
			}
		}

 		this.DBaseCookieProperties.CookieString = s
		if (typeof(document) == "undefined") {
			//Server side - ASP
			var cookie = s //no need of escape - automatically done
			var cookieName = this.DBaseProperties.Name
			eval("Response.Cookies(cookieName) = cookie") //statement 'hidden' cause Netscape doesnt like, even though it never executes this code 
			Response.Cookies(cookieName).Expires = expireon//"15-8-1981 21:31:00"
		} else {
			//Client side
			var sEscape = escape(s)
			var cookie = this.DBaseProperties.Name + this.DBaseCookieProperties.SeparatorDBName + sEscape + cookieExtras
			this.DBaseCookieProperties.CookieLength = sEscape.length
			this.DBaseCookieProperties.Document.cookie = cookie
		}

		return true
	} else {
		//no cookie
		return false
	}
}

function _cookie_load() {
	var cookieStr = ""
	mycookie = ""

	if (typeof(document)=="undefined") {
		//Server side - ASP
		cookieStr = Request.Cookies(this.DBaseProperties.Name).Item
		
		if (cookieStr == "") {
			//create and load cookie recordset
			if ((this.DBaseProperties.CreateCookieRecordset == true) && (typeof(this.DBaseCookieRecordset) == "undefined")) {
				this.CreateCookieRecordset()
				this.LoadCookieRecordset()
			}
			return false
		}

		cookieStr = unescape(cookieStr)
		mycookie = cookieStr
	} else {
	
		//Client side
		if (this.DBaseCookieProperties.Document=="") {this.DBaseCookieProperties.Document=document
		cookieStr = this.DBaseCookieProperties.Document.cookie}
		
		if (cookieStr == "") {
			//create and load cookie recordset
			if ((this.DBaseProperties.CreateCookieRecordset == true) && (typeof(this.DBaseCookieRecordset) == "undefined")) {
				
				this.CreateCookieRecordset()
				this.LoadCookieRecordset()
			}
			return false
		}	
 		//incase cookie was saved server side replace '+' with space
		var temp = cookieStr.replace(/\+/g,' ')
		cookieStr = temp 
		cookieStr = unescape(cookieStr)
			
		
		var startString = this.DBaseProperties.Name + this.DBaseCookieProperties.SeparatorDBName
		var startLength = (startString).length
		var start = cookieStr.indexOf(startString)

		if (start == -1) {
			this.DBaseCookieProperties.Loaded=false
			//create and load cookie recordset
			if ((this.DBaseProperties.CreateCookieRecordset == true) && (typeof(this.DBaseCookieRecordset) == "undefined")) {
				this.CreateCookieRecordset()
				this.LoadCookieRecordset()
			}
			return false
		}
		start += startLength

		var end = cookieStr.indexOf(this.DBaseCookieProperties.SeparatorEnd,start)
		if (end == -1) end = cookieStr.length
		mycookie = cookieStr.substring(start,end)
	}

	//set CookieString property
	this.DBaseCookieProperties.CookieString = mycookie
	this.DBaseCookieProperties.CookieLength = escape(mycookie).length
	
	//start create recordsets
	var temp = new Array() //holds rset names
	temp = this.DBaseCookieProperties.CookieString.split(this.DBaseCookieProperties.SeparatorRsets)
	
	var nofRsets = temp.length
	
	for (var r=0;r<nofRsets;r++) {
		//split for rsetname
		var RsetFieldsRecs = new Array()
		RsetFieldsRecs = temp[r].split(this.DBaseCookieProperties.SeparatorRsetDefinition)
		var RsetName = RsetFieldsRecs[0]
		
		if (this.Recordsets(RsetName) == false) { //if rset does not exist then create, else reset rest and reload from cookie
			this.CreateRecordset(RsetName)
			this.Recordsets(RsetName).RsetProperties.CookieOn = true //switch on cookie create for this recordset
	
			//split for fieldnames/dbIndex/Type
			var FieldNames = new Array()
			var FielddbIndex = new Array()
			var FieldType = new Array()
			FieldNames = RsetFieldsRecs[1].split(this.DBaseCookieProperties.SeparatorFieldNames)
			FielddbIndex = RsetFieldsRecs[2].split(this.DBaseCookieProperties.SeparatorFielddbIndex)
			FieldType = RsetFieldsRecs[3].split(this.DBaseCookieProperties.SeparatorFieldType)
			for (var f=0;f<FieldNames.length;f++) {
				if (FielddbIndex[f] == "true") {
					this.Recordsets(RsetName).CreateField(FieldNames[f],dbIndex)
				} else {
					this.Recordsets(RsetName).CreateField(FieldNames[f])
				}
				this.Recordsets(RsetName).Fields(f).FieldProperties.Type = FieldType[f] 
			}
		} else {
			this.ResetRecordset(RsetName)
			this.Recordsets(RsetName).RsetProperties.CookieOn = true
		}
		
		//split for records
		var Recs = new Array()
		Recs = RsetFieldsRecs[4].split(this.DBaseCookieProperties.SeparatorRecords)
		var nofRecs = Recs.length
		for (var recs=0;recs<nofRecs;recs++) {
			var myRec = new Array()
			myRec = Recs[recs].split(this.DBaseCookieProperties.SeparatorFieldValues)
			if (myRec == "") break
			this.Recordsets(RsetName).A(myRec)
		}	
	}
	
	//create and load cookie recordset
	if ((this.DBaseProperties.CreateCookieRecordset == true) && (typeof(this.DBaseCookieRecordset) != "undefined")) {
		this.LoadCookieRecordset()
	}
			
	this.DBaseCookieProperties.Loaded=true
	return true
}


function _cookie_remove() {
	if (typeof(document)=="undefined") {
		//ASP
		//NOTE need to change below PATH DOMAIN ETC
		
		cookieName = this.DBaseProperties.Name
		eval("Response.Cookies(cookieName) = cookie") //statement 'hidden' cause Netscape doesnt like, even though it never executes this code 
		if (this.DBaseCookieProperties.Path) Response.Cookies(cookieName).Path = this.DBaseCookieProperties.Path
		if (this.DBaseCookieProperties.Domain) Response.Cookies(cookieName).Domain = this.DBaseCookieProperties.Domain
		Response.Cookies('user').Expires = "01-10-1980 00:00:00"
		this.DBaseCookieProperties.Loaded = false
	} else {
		var cookie = this.DBaseProperties.Name + this.DBaseCookieProperties.SeparatorDBName
		if (this.DBaseCookieProperties.Path) cookie += '; path=' + this.DBaseCookieProperties.Path
		if (this.DBaseCookieProperties.Domain) cookie += '; domain=' + this.DBaseCookieProperties.Domain
		cookie += ';expires=Fri, 02-Jan-1970 00:00:00 GMT'

		if (this.DBaseCookieProperties.Document == "") this.DBaseCookieProperties.Document=document
		this.DBaseCookieProperties.Document.cookie = cookie
		this.DBaseCookieProperties.Loaded = false
	}
	return true
}
  
function _create_cookie_recordset() {
	if (this.DBaseProperties.CreateCookieRecordset == true) {
		this.CreateRecordset('DBaseCookieRecordset')
		with (this.DBaseCookieRecordset) {
			CreateField('Domain')
			CreateField('Expires')
			CreateField('ExpireHours')
			CreateField('ExpireMinutes')
			CreateField('Path')
			CreateField('Secure')
			
			RsetProperties.CookieOn = true
		}
		var Domain = this.DBaseCookieProperties.Domain
		var Expires = this.DBaseCookieProperties.Expires
		var ExpireHours = this.DBaseCookieProperties.ExpireHours
		var ExpireMinutes = this.DBaseCookieProperties.ExpireMinutes
		var Path = this.DBaseCookieProperties.Path
		var Secure = this.DBaseCookieProperties.Secure
		this.DBaseCookieRecordset.AddRec([Domain,Expires,ExpireHours,ExpireMinutes,Path,Secure])
	}
}
 
function _load_cookie_recordset() {
	if (this.DBaseProperties.CreateCookieRecordset == true) {
		this.DBaseCookieRecordset.MoveFirst()
		
		with (this.DBaseCookieRecordset) {
			this.DBaseCookieProperties.Domain = Domain
			this.DBaseCookieProperties.Expires = Expires
			this.DBaseCookieProperties.ExpireHours = ExpireHours
			this.DBaseCookieProperties.ExpireMinutes = ExpireMinutes
			this.DBaseCookieProperties.Path = Path
			this.DBaseCookieProperties.Secure = eval(Secure)
		} 
	}
}

Database.prototype.CookieSave = _cookie_save
Database.prototype.CookieLoad = _cookie_load
Database.prototype.CookieRemove = _cookie_remove
Database.prototype.CreateCookieRecordset = _create_cookie_recordset
Database.prototype.LoadCookieRecordset = _load_cookie_recordset

//%>
