/*
AccessObject-JavaScriptDatabase (v3.47)
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/2001 Kevin Gibney
Distributed under the terms of the GNU Library General Public License
*/

//start universal variables
var dbIndex=1,
	dbPrimaryKey = dbIndex,
	dbTypeBoolean = 240,
	dbTypeCurrency = 260,
	dbTypeDate = 250,
	dbTypeInteger = 220,
	dbTypeReal = 230,
	dbTypeText = 210;
//end universal variables
 
//***START DATABASE DEFINITION***
	//**Database Object
function Database(name) {
	this.DBaseProperties = new DatabaseProperties()
	this.DBaseProperties.Name = name
	if (typeof(CookieProperties) != "undefined") 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.key_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.ResetRecordset = _reset_recordset

	//**Database Properties
function DatabaseProperties() {
	this.Name
	this.AOJDVersion="3.47"
	this.AOJDLastUpdated="11/10/2001"
}
//***END DATABASE DEFINITION***


//***START RECORDSET DEFINITION***
function Recordset() {
	this.RsetProperties = new RecordsetProperties() 
	this.RsetRecs = new Array()	//records 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.key_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.key_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.BOF = _bof
	Recordset.prototype.CreateField = _create_field
	Recordset.prototype.ChangeQuery = _change_query
	Recordset.prototype.Count = _count
	Recordset.prototype.CompareRows = _compare_rows
	Recordset.prototype.CreateQueryArrays = _create_query_arrays
	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.Get = _get
	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(prop,value) {
	this.BadQuery=false
	this.Bof=false
	this.CookieOn = false
	this.CurrentRecord=-1
	this.CurrentQuery=""
	this.CurrentQueryChanged=""
	this.Eof=false
	this.IndexedField = new Object()
	this.MyDatabase 
	this.Name=""
	this.NoMatch=false
	this.OrdinalPosition=-1
	this.PagesArray = new Array()
	this.RecordsArray = new Array()
	this.RecordProperties
	this.RecsDeleted=0
	this.RecsUndeleted=0
} 
	//**Field Properties
function FieldProperties() {
	this.Indexed = false
	this.Name = ""
	this.OrdinalPosition = -1
	this.Type = ""
	this.Value = ""
}
	//**Record Properties
function RecordProperties() {
	this.Deleted = false
	this.PrimaryKeyName = ""
}
//***END RECORDSET DEFINITION***

//**Start Collection Methods
function _collection_add(item,key) {
	this.object_list[key]=item
	this.array_list[this.array_list.length]=item
	this.key_array_list[this.key_array_list.length]=key 
	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

//**Start Database 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 {
		return false
	}
}
function _reset_recordset(name) {
	this.Recordsets(name).RsetRecs = new Array()		
	with (this.Recordsets(name).RsetProperties) {
		BadQuery=false
		Bof=false
		CookieOn = false
		CurrentRecord=-1
		CurrentQuery=""
		CurrentQueryChanged=""
		Eof=false
		IndexedField = new Object()
		//MyDatabase 
		//Name=""
		NoMatch=false
		//OrdinalPosition=-1
		PagesArray = new Array()
		RecordsArray = new Array()
		RecordProperties.Deleted = false
		RecordProperties.PrimaryKeyName = ""
		RecsDeleted=0
		RecsUndeleted=0
	}
	for (var i=0; i < this.Recordsets(name).Fields.Count; i++) {
		//this.Indexed = false
		//this.Name = ""
		//this.OrdinalPosition = -1
		//this.Type = ""
		this.Recordsets(name).Fields(i).FieldProperties.Value = ""
	}
	
}
//**End database methods

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==dbPrimaryKey) {
			this.Indexed.Add(this[fieldname],fieldname)
			this[fieldname].FieldProperties.Indexed = true
		}
		return true
	}
	else {
		return false
	}
}

function _add_rec0(fields) {
	var pRR = this.RsetRecs, pRP = this.RsetProperties, ridx = pRR.length;
	pRP.RecsUndeleted++
	pRR[ridx] = fields
	pRR[ridx].RecordProperties = new RecordProperties()
}
function _add_rec1(fields) {
	var pRR = this.RsetRecs, pRP = this.RsetProperties, ridx = pRR.length,
		aPrimaryKeyValue = fields[this.Indexed.array_list[0].FieldProperties.OrdinalPosition];
	if (typeof(pRP.IndexedField[aPrimaryKeyValue]) != "undefined") {alert('Error you are trying to create a record with a duplicate primary key field in recordset: ' + pRP.Name + '  with primary key value:' + aPrimaryKeyValue)}
	pRP.RecsUndeleted++
	pRR[ridx] = fields
	pRR[ridx].RecordProperties = new RecordProperties()

	pRP.IndexedField[aPrimaryKeyValue] = ridx
	pRR[ridx].RecordProperties.PrimaryKeyName = aPrimaryKeyValue
}
function _add_rec2(fields) {
	var pRR = this.RsetRecs, pRP = this.RsetProperties, ridx = pRR.length,
		aPrimaryKeyValue = fields[this.Indexed.array_list[0].FieldProperties.OrdinalPosition] + "_" + fields[this.Indexed.array_list[1].FieldProperties.OrdinalPosition];
	if (typeof(pRP.IndexedField[aPrimaryKeyValue]) != "undefined") {alert('Error you are trying to create a record with a duplicate primary key field in recordset: ' + pRP.Name + '  with primary key value:' + aPrimaryKeyValue)}
	pRP.RecsUndeleted++
	pRR[ridx] = fields
	pRR[ridx].RecordProperties = new RecordProperties()

	pRP.IndexedField[aPrimaryKeyValue] = ridx
	pRR[ridx].RecordProperties.PrimaryKeyName = aPrimaryKeyValue
}
function _add_recMORE(fields) { 
	var pRR = this.RsetRecs, pRP = this.RsetProperties, ridx = pRR.length;

	var arrPK=new Array(),aPrimaryKeyValue;
	for (var i=0;i<this.Indexed.Count;i++) {
		arrPK[i]=fields[this.Indexed.array_list[i].FieldProperties.OrdinalPosition]
	}
	aPrimaryKeyValue = arrPK.join('_')
	if (typeof(pRP.IndexedField[aPrimaryKeyValue]) != "undefined") {alert('Error you are trying to create a record with a duplicate primary key field in recordset: ' + pRP.Name + '  with primary key value:' + aPrimaryKeyValue)}
	pRP.RecsUndeleted++
	pRR[ridx] = fields
	pRR[ridx].RecordProperties = new RecordProperties()

	pRP.IndexedField[aPrimaryKeyValue] = ridx
	pRR[ridx].RecordProperties.PrimaryKeyName = aPrimaryKeyValue
}

function _add_rec(fields) {
	if (this.Indexed.Count == 0) this.A = _add_rec0
	else if (this.Indexed.Count == 1) this.A = _add_rec1
	else if (this.Indexed.Count == 2) this.A = _add_rec2
	else this.A =_add_recMORE
	this.A(fields)
}

function _delete_rec() {
	var pRP = this.RsetProperties,pRR=this.RsetRecs;
	if (pRP.RecsUndeleted==0) return false
	if (pRP.CurrentRecord==-1) {alert('Error you have to select a record to delete.'); return false}
	if (pRR[pRP.CurrentRecord].RecordProperties.Deleted == true) {alert('Error current record has been deleted.');return false}
	pRR[pRP.CurrentRecord].RecordProperties.Deleted = true
	pRP.RecsDeleted++
	pRP.RecsUndeleted--
	this.SetCurrentFields()
	return true
}

function _recdeleted() {
	if (typeof(this.RsetRecs[this.RsetProperties.CurrentRecord]) != "undefined") {
		return this.RsetRecs[this.RsetProperties.CurrentRecord].RecordProperties.Deleted
	} else {
		return this.RsetRecs[this.RsetProperties.CurrentRecord]
	}
}

function _update_field(field,newvalue) {
	var pF = this.Fields(field), pRP = this.RsetProperties;
	if (pRP.CurrentRecord==-1) {alert('Error you have to select a record to update.'); return false}
	if (pF == false) {
		alert('Cannot update field, field not created for this recordset: ' + field)
		return false
	}
	if (pF.FieldProperties.Indexed==true) {
		alert('Error:\n\nYou cannot update an Indexed field.\n\nField='+field)
		return false
	}
	this.RsetRecs[pRP.CurrentRecord][pF.FieldProperties.OrdinalPosition] = newvalue
	this.SetCurrentFields()
	return true
}

function _reset_indexed() {
	var iRecCount = this.RsetRecs.length, pRsetRecs = this.RsetRecs, pIndexedField = this.RsetProperties.IndexedField;		
	for (var ridx=0;ridx<iRecCount;ridx++) pIndexedField[pRsetRecs[ridx].RecordProperties.PrimaryKeyName] = ridx
}

function _set_current_fields() {
	var iFieldCount=this.Fields.Count, pFP,	pRR = this.RsetRecs, pRP = this.RsetProperties,	FieldValue,
		recArrayIndex = pRP.CurrentRecord;

	if ((pRP.RecsUndeleted==0) || (typeof(pRR[recArrayIndex]) == "undefined")) return false
	for (var fidx=0;fidx<iFieldCount;fidx++) {
		pFP = this.Fields(fidx).FieldProperties
		FieldValue = pRR[recArrayIndex][fidx]
		this[pFP.Name]=FieldValue
		pFP.Value=FieldValue
	}
	pRP.RecordProperties = pRR[recArrayIndex].RecordProperties
	return true
}

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.SetCurrentFields()
		}
	} 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.SetCurrentFields()
		}
	} 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.SetCurrentFields()
		}		
	} 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.SetCurrentFields()
		}		
	} else {
		this.RsetProperties.NoMatch=true
		this.RsetProperties.CurrentRecord=temp
		this.EOF()
		this.BOF()
		this.SetCurrentFields()
	}
}

function _find(direction, query) {
	var pRP = this.RsetProperties, pRR = this.RsetRecs, ridx, new_query;
	pRP.NoMatch = true
	if (pRP.CurrentQuery!=query) {
		new_query=this.ChangeQuery(query) + ""
		if (pRP.BadQuery) return -1
	} else {
		new_query=pRP.CurrentQueryChanged
	}

	ridx = pRP.CurrentRecord
	iRecordCount = pRR.length
	if (direction=="forward") {
		for (ridx;ridx<iRecordCount;ridx++) {
			if ((!pRR[ridx].RecordProperties.Deleted) && (eval(new_query))) {	
				pRP.CurrentRecord=ridx
				pRP.NoMatch=false
				break
			}
		}
	} else {
		for (ridx;ridx>-1;ridx--) {
			if ((!pRR[ridx].RecordProperties.Deleted) && (eval(new_query))) {
				pRP.CurrentRecord=ridx
				pRP.NoMatch=false
				break
			}
		}
	}
	return true
}
//**End Find Methods

function _get(ridx) {
	var pRP = this.RsetProperties, pRR = this.RsetRecs;
	ridx = parseInt(ridx)
	if (isNaN(ridx)) {pRP.NoMatch = true;return false}
	if ((ridx < 0)||(ridx>=pRR.length)) {pRP.NoMatch = true;return false;}
	pRP.CurrentRecord = ridx
	if (pRR[ridx].RecordProperties.Deleted != true) {pRP.NoMatch = false;this.SetCurrentFields();return true;}
	pRP.NoMatch = true;	return false;
}

function _seek() {
	var key, a = new Array(), pRP = this.RsetProperties;
	if (arguments.length != this.Indexed.Count) {
		alert('Error: Wrong numbers of arguments to .Seek(), should be ' + this.Indexed.Count + ' for recordset ' + pRP.Name)
		return false
	}
	for (var i=0;i<arguments.length;i++) {
		a[i] = arguments[i]
	}
	key = (arguments.length > 1)?a.join('_'):a[0]
	if (typeof(pRP.IndexedField[key]) != "undefined") {
		pRP.CurrentRecord = pRP.IndexedField[key]
		pRP.NoMatch = false
		this.SetCurrentFields()
		return true
	}
	pRP.NoMatch = true
	return false
}

function _change_query(query) {
	var iFieldCount=this.Fields.Count,strEnd,strStart;
	this.RsetProperties.CurrentQuery=query
	this.RsetProperties.BadQuery=true 
	query = "(" + query + ")"
	for (var fidx=0;fidx<iFieldCount;fidx++) {
		var	sFieldName = this.Fields(fidx).FieldProperties.Name,
			lenFieldName = sFieldName.length,
			myRegCheck = eval("/[^0-9a-zA-Z_]{1}" + sFieldName + "[^0-9a-zA-Z_]{1}/"),
			iFound=query.search(myRegCheck);
		if (iFound != -1) {
			this.RsetProperties.BadQuery=false
			var replace_string = "this.RsetRecs[ridx][" + fidx + "]"
			while (iFound != -1) {
				strStart = query.substr(0,iFound+1)
				strEnd = query.substr((iFound+1)+(lenFieldName),(query.length-1))
				query = strStart + replace_string + strEnd
				iFound = query.search(myRegCheck)
			}
		}
	}
	this.RsetProperties.CurrentQueryChanged=query
	return query
}

function _create_query_arrays(query,pageSize) {
	var countRecs=1, new_query,	pRP = this.RsetProperties, pRR = this.RsetRecs, iRsetRecsCount = pRR.length;

	pRP.RecordsArray = new Array()
	pRP.PagesArray = new Array()
	if (pRP.CurrentQuery!=query) {
		new_query=this.ChangeQuery(query) + ""
		if (pRP.BadQuery) return -1
	} else {
		new_query=pRP.CurrentQueryChanged
	}
	if (arguments.length==1) {
		for (var ridx=0; ridx<iRsetRecsCount; ridx++) {
			if ((!pRR[ridx].RecordProperties.Deleted) && (eval(new_query))) {
				pRP.RecordsArray[pRP.RecordsArray.length] = ridx
			}
		}
	} else {
		if (pRP.RecsDeleted == 0) {
			for (var ridx=0; ridx<iRsetRecsCount; ridx++) {
				if (eval(new_query)) {
					pRP.RecordsArray[pRP.RecordsArray.length] = ridx
					if (countRecs==1) pRP.PagesArray[pRP.PagesArray.length] = ridx
					if (countRecs==pageSize) countRecs=1
					else countRecs++
				}
			}
		} else {
			for (var ridx=0; ridx<iRsetRecsCount; ridx++) {
				if ((!pRR[ridx].RecordProperties.Deleted) && (eval(new_query))) {
					pRP.RecordsArray[pRP.RecordsArray.length] = ridx
					if (countRecs==1) pRP.PagesArray[pRP.PagesArray.length] = ridx
					if (countRecs==pageSize) countRecs=1
					else countRecs++
				}
			}
		}
	}
	pRP.NoMatch=false
}

function _sort(fields,orders) {
	this.MoveFirst()
	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 false
		}
		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 false
		}
	}
	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()
	return true
}
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
	}
}

function _count(query) {
	var pRP = this.RsetProperties, pRR = this.RsetRecs, iRsetRecsCount = pRR.length, new_query, count=0;
	if ((typeof(query) == "undefined") || query == "") {
		pRP.NoMatch=false
		return pRP.RecsUndeleted
	}
	if (pRP.CurrentQuery!=query) {
		new_query=this.ChangeQuery(query) + ""
		if (pRP.BadQuery) return -1
	} else {
		new_query=pRP.CurrentQueryChanged
	}
	for (var ridx=0; ridx<iRsetRecsCount; ridx++) {
		if ((!pRR[ridx].RecordProperties.Deleted) && eval(new_query)) {
			count++
		}
	}
	(count==0)?pRP.NoMatch=true:pRP.NoMatch=false
	return count
}

function _dump_recordset(fNames,fDelimitor,rDelimitor) {
	var pRP = this.RsetProperties,	iCountRecords = pRP.RecsUndeleted, iMaxRecID = (this.RsetRecs.length-1),
		iCountFields = fNames.length, s = "", sRec = "";

	if (iCountRecords == 0) return "no records available"
	this.MoveFirst()
	while (!pRP.Eof) {
		for (var i=0;i<iCountFields;i++) {
			if (sRec != "") sRec += fDelimitor
			sRec += this.Fields(fNames[i]).FieldProperties.Value
		}
		s += sRec
		if (pRP.CurrentRecord < iMaxRecID) s+=rDelimitor 
		sRec = ""
		this.MoveNext()
	}
	return s
}

/*
CookieMethods(v2.1) for Access-Object JavaScript Database
Latest Version and help file available at http://www.javascriptdatabase.com

Copyright (C) 2001 Kevin Gibney
Distributed under the terms of the GNU Library General Public License
*/

function CookieProperties() {
	this.AOJDCookieVersion = '2.1'
	
	//these properties are fields in DBaseCookieRecordset.
	this.Domain = ''		//rw	string
	this.Expires = -1		//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(){
	var pCRset = this.DBaseCookieRecordset, 
		pCProp = this.DBaseCookieProperties,
		pDBProp = this.DBaseProperties;
	
	if (this.Recordsets.Count > 0) {
		//create and load cookie recordset
		if (typeof(pCRset) != "undefined") {
			this.LoadCookieRecordset()
		}
		
		//setup expires
		if (typeof(document)=="undefined") {
			//***ASP - SERVER SIDE
			//Note: date.toGMTString() function does not seem to work in my version of win2000 server side - hence the hack
			var expiretime = 0
			if (pCProp.ExpireHours != 0)  expiretime=pCProp.ExpireHours*(1000*60*60)
			if (pCProp.ExpireMinutes != 0)  expiretime+=pCProp.ExpireMinutes*(1000*60)
	
			if (expiretime != 0) pCProp.Expires = new Date((new Date()).getTime() + expiretime)

			var myyear = pCProp.Expires.getFullYear()
			var mymonth = pCProp.Expires.getMonth() + 1
			var myday = pCProp.Expires.getDate()
			
			var myHH = pCProp.Expires.getHours()
			var myMM = pCProp.Expires.getMinutes()
			var mySS = pCProp.Expires.getSeconds()
			var expireon = myday + "-" + mymonth + "-" + myyear + " " + myHH + ":" + myMM + ":" + mySS
			//.toGMTString()does not work
		} else {
			//***CLIENT SIDE			
			var expiretime = 0
			if (pCProp.ExpireHours != 0)  expiretime=pCProp.ExpireHours*(1000*60*60)
			if (pCProp.ExpireMinutes != 0)  expiretime+=pCProp.ExpireMinutes*(1000*60)
	
			if (expiretime != 0) pCProp.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=' + pCProp.Expires.toUTCString()
			if (pCProp.Path != '') cookieExtras += '; path=' + pCProp.Path
			if (pCProp.Domain != '') cookieExtras += '; domain=' + pCProp.Domain
			if (pCProp.Secure != false) cookieExtras += '; secure'
		}
		with (this.DBaseCookieRecordset) {
			MoveFirst()
			UpdateField('Expires',pCProp.Expires.toUTCString())
		}
		
		var s = '', startRsetLoop = true;
		for (var r=0;r<this.Recordsets.Count;r++) {
			var pRset = this.Recordsets(r)
			if (pRset.RsetProperties.CookieOn) {
				//recordsets separator
				if (!startRsetLoop) s+= pCProp.SeparatorRsets
				startRsetLoop = false
				
				//recordset name
				s += pRset.RsetProperties.Name + pCProp.SeparatorRsetDefinition
				
				//fieldproperties: Name,Indexed,Type
				var sFN="",sFI="",sFT=""
				if (pRset.Fields.Count>0) {	
					sFN = pRset.Fields(0).FieldProperties.Name
					sFI = pRset.Fields(0).FieldProperties.Indexed
					sFT = pRset.Fields(0).FieldProperties.Type
				}
				for (var f=1;f<this.Recordsets(r).Fields.Count;f++) {
					sFN += pCProp.SeparatorFieldNames + pRset.Fields(f).FieldProperties.Name
					sFI += pCProp.SeparatorFielddbIndex + pRset.Fields(f).FieldProperties.Indexed
					sFT += pCProp.SeparatorFieldType + pRset.Fields(f).FieldProperties.Type
				}
				s += sFN + pCProp.SeparatorRsetDefinition
				s += sFI + pCProp.SeparatorRsetDefinition
				s += sFT + pCProp.SeparatorRsetDefinition
				
				//save recordset records
				var sR = ""
				if (pRset.Count() > 0) {
					var startRecordLoop = true, currentrec
					pRset.MoveFirst()
					while (!pRset.RsetProperties.Eof) {
						currentrec=pRset.RsetProperties.CurrentRecord
						if (pRset.RsetRecs[currentrec].RecordProperties.Deleted==false) {
							if (!startRecordLoop) sR += pCProp.SeparatorRecords
							sR += pRset.RsetRecs[currentrec].join(pCProp.SeparatorFieldValues)
							startRecordLoop = false
						}
						pRset.MoveNext()
						
					}
					s += sR
				}
			}
		}

 		pCProp.CookieString = s
		if (typeof(document) == "undefined") {
			//***ASP - SERVER SIDE
			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 = pDBProp.Name + pCProp.SeparatorDBName + sEscape + cookieExtras
			pCProp.CookieLength = sEscape.length
			pCProp.Document.cookie = cookie
		}
		pCProp.Loaded = true
		return true
	} else {
		//no cookie
		return false
	}
}

function _cookie_load() {
	var pCRset = this.DBaseCookieRecordset, pCProp = this.DBaseCookieProperties, pDBProp = this.DBaseProperties,
		cookieStr = "",	mycookie = "";

	if (typeof(document)=="undefined") {
		//Server side - ASP
		cookieStr = Request.Cookies(pDBProp.Name).Item
		
		if (cookieStr == "") {
			//create and load cookie recordset
			if (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 (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 = pDBProp.Name + pCProp.SeparatorDBName
		var startLength = (startString).length
		var start = cookieStr.indexOf(startString)

		if (start == -1) {
			pCProp.Loaded=false
			//create and load cookie recordset
			if (typeof(this.DBaseCookieRecordset) == "undefined") {
				this.CreateCookieRecordset()
				this.LoadCookieRecordset()
			}
			return false
		}
		start += startLength

		var end = cookieStr.indexOf(pCProp.SeparatorEnd,start)
		if (end == -1) end = cookieStr.length
		mycookie = cookieStr.substring(start,end)
	}

	//set CookieString property
	pCProp.CookieString = mycookie
	pCProp.CookieLength = escape(mycookie).length
	
	//start create recordsets
	var temp = new Array() //holds rset names
	temp = pCProp.CookieString.split(pCProp.SeparatorRsets)
	
	var nofRsets = temp.length
	for (var r=0;r<nofRsets;r++) {
		//split for rsetname
		var RsetFieldsRecs = new Array()
		RsetFieldsRecs = temp[r].split(pCProp.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(pCProp.SeparatorFieldNames)
			FielddbIndex = RsetFieldsRecs[2].split(pCProp.SeparatorFielddbIndex)
			FieldType = RsetFieldsRecs[3].split(pCProp.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(pCProp.SeparatorRecords)
		var nofRecs = Recs.length
		for (var recs=0;recs<nofRecs;recs++) {
			var myRec = new Array()
			myRec = Recs[recs].split(pCProp.SeparatorFieldValues)
			if (myRec == "") break
			this.Recordsets(RsetName).A(myRec)
		}	
	}
	
	//create and load cookie recordset
	if (typeof(this.DBaseCookieRecordset) != "undefined") {
		this.LoadCookieRecordset()
	}
			
	pCProp.Loaded=true
	return true
}


function _cookie_remove() {
	var pCProp = this.DBaseCookieProperties, pDBProp = this.DBaseProperties;
	if (typeof(document)=="undefined") {
		//***ASP - SERVER SIDE
		//NOTE need to change below PATH DOMAIN ETC
		
		var cookieName = pDBProp.Name
		eval("Response.Cookies(cookieName) = cookie") //statement 'hidden' cause Netscape doesnt like, even though it never executes this code 
		if (pCProp.Path) Response.Cookies(cookieName).Path = pCProp.Path
		if (pCProp.Domain) Response.Cookies(cookieName).Domain = pCProp.Domain
		Response.Cookies('user').Expires = "01-10-1980 00:00:00"
		pCProp.Loaded = false
	} else {
		//***CLIENT SIDE
		var cookie = pDBProp.Name + pCProp.SeparatorDBName
		if (pCProp.Path) cookie += '; path=' + pCProp.Path
		if (pCProp.Domain) cookie += '; domain=' + pCProp.Domain
		cookie += ';expires=Fri, 02-Jan-1970 00:00:00 GMT'

		if (pCProp.Document == "") pCProp.Document=document

		pCProp.Document.cookie = cookie
		pCProp.Loaded = false
	}
	return true
}

function _create_cookie_recordset() {
	var pCProp = this.DBaseCookieProperties;
	this.CreateRecordset('DBaseCookieRecordset')
	with (this.DBaseCookieRecordset) {
		CreateField('Domain')
		CreateField('Expires')
		CreateField('ExpireHours')
		CreateField('ExpireMinutes')
		CreateField('Path')
		CreateField('Secure')
		
		RsetProperties.CookieOn = true
	}
	this.DBaseCookieRecordset.AddRec([pCProp.Domain,pCProp.Expires,pCProp.ExpireHours,pCProp.ExpireMinutes,pCProp.Path,pCProp.Secure])
}
 
function _load_cookie_recordset() {
	var pCRset = this.DBaseCookieRecordset, pCProp = this.DBaseCookieProperties;
	pCRset.MoveFirst()
	with (this.DBaseCookieRecordset) {
		pCProp.Domain = Domain
		pCProp.Expires = Expires
		pCProp.ExpireHours = ExpireHours
		pCProp.ExpireMinutes = ExpireMinutes
		pCProp.Path = Path
		pCProp.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