//--------------------------------
// general v1.1
//--------------------------------
var NULL_VALUE = '[null]';

function on_document_key_down(e)
{
	switch (get_code(e))
	{
		case 13:
			if (focus_field != null)
			{
				if (focus_field.type != undefined)
				{
					if (focus_field.tagName == 'LABEL')
					{
						
					}
					else
					{
						
						switch (focus_field.type)
						{
	//						case 'image':
	//						case 'button':
							case 'textarea':
								break;
							default:
								if (focus_field.form != undefined && focus_field.form.onsubmit != null)
								{
									if (focus_field.form.onsubmit())
									{
										focus_field.form.submit();
									}
									return cancel_bubble(e);
								}
						}				
					}
				}
			}
			break;
		case 27:
			//escape does not work in firefox
			if (isIE)
				return !document_key_escape();
			break;
		case 33:
			//page up
			if (isIE)
				if (scrolled_to_start())
					return !safe_click('page_back');
			break;
		case 34:
			//page down
			if (isIE)
				if (scrolled_to_end())
					return !safe_click('page_forward');
			break;
		case 36:
			//home
			if (isIE)
				if (focus_field != null)
					if (scrolled_to_start())
						return !safe_click('page_start');
			break;
		case 35:
			//End
			if (isIE)
				if (focus_field != null)
					if (scrolled_to_end())
						return !safe_click('page_end');
			break;
		case 45:
			// insert
			//if (focus_field.type == '' || focus_field.name == 'page')
			return !safe_click('new_but');
			break;
		case 46:
			//delete
			return !safe_click('delete_but');
			break;
		case 113:
			//F2
			return !safe_click('edit_but');
			break;		
	}
	return true;
}
document.onkeydown = on_document_key_down;
function get_code(event)
{
	if (event == undefined) event = window.event;
	return event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
}

//function get_option_under_mouse(event)
//{
//	if (event == undefined) event = window.event;
//	var sel;
//	if (event.srcElement)
//	{
//		//ie
//		sel = event.srcElement;
//		y = event.offsetY;
//	}
//    else if (mEvent.target)
//    {
//	    // Netscape and Firefox
//		sel = event.target;
//		y = event.offsetY;
//	}
//	var optionHeight = parseInt(sel.offsetHeight / sel.size);
//	var iStart = parseInt(sel.scrollTop / optionHeight);
//	var iOver = parseInt(y / optionHeight);
//	sel.getElementsByTagName('OPTGROUP')
//	return iStart + iOver;
//
function get_scroll_top()
{
	if (isIE)
	{
		if (!document.documentElement.scrollTop)
            return document.body.scrollTop;
         else
            return document.documentElement.scrollTop;
	}
    else
		return window.pageYOffset;
}

function scrolled_to_start()
{
	if (get_scroll_top() == 0)
		return true;
}
function scrolled_to_end()
{
	if (get_scroll_top() + document.documentElement.offsetHeight >= document.documentElement.scrollHeight)
		return true;
}
function safe_click(id)
{
	var but = elementFromid(id);
	if (but != undefined) 
	{
		if (but.tagName == 'A')
			return click_link(id);
		else
		{
			but.click();
			return true;
		}
	}
}
function safe_disable(but,disabled)
{
	var but = elementFromid(but);

	if (but != undefined) 
	{
		if (but.tagName != 'A')
		{
			but.disabled = disabled;
		}
	}
}
function href_disable()
{
	alert('disabled');
	return false;
}
function safe_focus(field)
{
	try 
	{ 
		field.focus();
	} catch(e) 
	{
		//alert('a');
	};
}

//--------------------------------
// admin
//--------------------------------

var admin_child = null;
function admin_open(url)
{
	url = METADATA_URL + '/generic/pages/' + url + '&website=' + WEBSITE;
	if (child_window_open(admin_child))
	{
		admin_child.location = url;
	}
	else
	{
		admin_child = window.open(url, '', 'dependent=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes');
	}
}

function admin_edit(website)
{
	admin_open('/generic/pages/record.aspx?table=col_detail&mode=edit&key=' + get_keys(''));
	return false;
}

function set_admin()
{
	var url = get_url('1');
	if (url != '')
	{
		url = ReplaceQs(url,'admin','y');
		replace_url(url);
	}
}
function set_layout(cid, sColumns, sSort, fDownload)
{
	if (fDownload)
	{
		download_link(cid,sColumns,sSort);
	}
	else
	{
		var url = get_url(cid);
		if (url != '')
		{
			url = ReplaceQs(url,'columns',sColumns);
			url = ReplaceQs(url,'sort',sSort);
			replace_url(url);
		}
	}
}

function do_init()
{
	window.focus();
}

var max_title_width = null;
function set_titles_width(cid)
{
	var row_count, name, title, td, width, column_name;
	row_count = elementFromid('rows_' + cid).value;
	if (row_count == 1)
	{
		var tds = document.getElementsBySelector('td.title');

		for (var i = 0; i < tds.length; i++)
		{
			td = tds[i];
			width = outer_size(td, 'width');

			if (max_title_width == null)
				max_title_width = new Object();

			if (td.parentNode.parentNode.parentNode.parentNode.className.indexOf('right') != -1)
				column_name = 'right';
			else
				column_name = 'left';

			if (max_title_width[column_name] == undefined)
				max_title_width[column_name] = 0;
			if (width > max_title_width[column_name])
				max_title_width[column_name] = width;
		}

		for (var i = 0; i < tds.length; i++)
		{
			td = tds[i];
			if (td.parentNode.parentNode.parentNode.parentNode.className.indexOf('right') != -1)
				column_name = 'right';
			else
				column_name = 'left';
			td.style.width = max_title_width[column_name] + 'px';	 
		}
	}
}

function set_focus(df, field_name)
{
	var i;
	var fFound = false;
	var field;

	if (df == undefined || df == null) return;
	if (typeof field_name == 'undefined')
		fFound = true;
	for(i = 0; i < df.elements.length; i++)
	{
		field = df.elements[i];
		if (field == null)
			break;
		if (fFound)
		{
			if (field.type != undefined)
			{
				if (field.type != 'hidden' && field.disabled == false && field.tabIndex != 1000 && field.tabIndex != -1)
				{
					if (field.type == 'radio' || field.type == 'checkbox')
						field = get_checked_option(field.form[field.name]);
					safe_focus(field);
					break;
				}
			}
		}
		else
		{
			if (field.name == field_name)
				fFound = true;
		}
	}
	return;
}

//--------------------------------
// query string
//--------------------------------

function instr(text,search)
{
	var j = 0;
	for (var i=0; i < text.length; i++)
	{
		if (text.charAt(i) == search.charAt(j))
		{
			j++;
			if (j >= search.length)
				return true;
		}
		else
			j = 0;
	}
	return false;
}

//locate parameter in querystring
//case insensitive must be valid parameter
// returns [start of parameter part of qs, start of parameter found, end of parameter found]


function findparam(stringIn,Name,sep,equal)
{
	var paramloc = new Array(2);
	var start = 0;
	
	// initialise array of results 
	paramloc[0] = 0;
	paramloc[1] = -1;
	paramloc[2] = -1;
	
	// if indicated do not try and process 'action' part of qs - skip it by 
	// searching for ?
	var HasAction = instr(stringIn,'.aspx');
	
	if (HasAction)
	{
		start = stringIn.indexOf("?", 0) + 1;
		if (start == 0)
		{
			paramloc[0] = stringIn.length + 1;
			return paramloc;
		}
	}
	
	// convert parameter part of qs and search parameter name to upper case
	var strSearch  = new String(sep+stringIn.substring(start));
	var strSearchUpper  = new String(strSearch.toUpperCase());
	var strParam = new String(sep+Name+equal);
	var strParamUpper = new String(strParam.toUpperCase());

	j = strSearchUpper.indexOf(strParamUpper,0);
	if (j == -1)
		return paramloc;
		
	// if parameter found, locate following & or end of string
	j = j + 1
	for(i = j; i < strSearchUpper.length; i++)
	{
		if (strSearchUpper.charAt(i) == sep)
			break;
	}
	
	// add back length of action part of qs
	j = j + start - 1;
	i = i + start - 1;
	
	//store results and return array
	paramloc[1] = j;
	paramloc[2] = i;
	return paramloc;
}
function RemoveQs(stringIn,Name,sep,equal)
{
	if (sep == undefined) sep = '&';
	if (equal == undefined) equal = '=';
	var paramloc = findparam(stringIn,Name,sep,equal);
	//parameter not found
	if (paramloc[1] == -1)
		return stringIn;
	// parameter to be removed is only parameter after ? - remove ? as well
	if (paramloc[0] == paramloc[1] - 1 && paramloc[2] == stringIn.length)
		return 	stringIn.substring(0,paramloc[0]);
	// if parameter is last parameter, remove preceeding & as well
	if (paramloc[2] == stringIn.length)
		return stringIn.substring(0,paramloc[1]-1);
	// remove parameter plus following &
	return stringIn.substring(0,paramloc[1]) + stringIn.substring(paramloc[2]+1);
}
function ReplaceQs(stringIn,Name,NewValue,sep,equal)
{
	if (NewValue == '') return RemoveQs(stringIn,Name,sep,equal);

	if (sep == undefined) sep = '&';
	if (equal == undefined) equal = '=';
	
	var NewParam = Name + equal + NewValue;
	if (stringIn == '') return NewParam;
	var paramloc = findparam(stringIn,Name,sep,equal);

	//parameter not found
	if (paramloc[1] == -1)
	{
		//if other parameters add delimiter
		if (stringIn.substring(stringIn.length) == '?')
			return stringIn + NewParam;
		else
		{
			if (stringIn.length == paramloc[0] - 1)
				return stringIn + '?' + NewParam;
			else
				return stringIn + sep + NewParam;
		}
	}
	//replace parameter found
	return stringIn.substring(0,paramloc[1]) + NewParam + stringIn.substring(paramloc[2]);
}
function AddQs(name,qs)
{
	var value = GetQs(qs,name);
	return AppendQs(name,value);
}
function AppendQs(name,value)
{
	if (value != undefined)
		if (value != '')
			return '&' + name + '=' + value;
	return '';
}
function AppendAttrib(name,value)
{
	if (value == undefined)
		return '';
	if (value == '')
		return '';
	
	return ',' + name + '=' + value;
}

function GetQs(stringIn,Name,sep,equal)
{
	if (sep == undefined) sep = '&';
	if (equal == undefined) equal = '=';
	var paramloc = findparam(stringIn,Name,sep,equal);
	if (paramloc[1] == -1)
		return '';
	else
		return stringIn.substring(stringIn.indexOf(equal,paramloc[1])+1,paramloc[2]);
}
function GetWhere(stringIn,ParentOnly)
{
	var sep = '&';
	var strOut = new String();	
	var strParm;
	var HasAction = instr(stringIn,'.aspx');

	if (HasAction)
		start = stringIn.indexOf("?", 0) + 1;
	else
		start = 0;
		
	var strSearch  = new String(stringIn.substr(start,1000) + sep);
	
	for (var i = -1,j=-1; (i = strSearch.indexOf(sep,i+1)) > 0;j = i)
	{
		strParm = strSearch.substring(j+1,i);
		if (strParm.substr(0,3).toLowerCase() == 'ff_' && !ParentOnly ||
			strParm.substr(0,7).toLowerCase() == 'parent=' ||
			strParm.substr(0,11).toLowerCase() == 'parent_key=' )
			strOut = strOut + strParm + sep;
	}
	if (strOut == '')
		return '';
	else
		return '&' + strOut.substr(0,strOut.length-1);
}
function GetPageName(url)
{
	var i = url.indexOf('.aspx');
	var j = url.indexOfRev('/',i);
	return url.substring(j+1,i);
}

//--------------------------------
// general helper
//--------------------------------

// overly simplistic test for IE
isIE = (document.all ? true : false);

// both IE5 and NS6 are DOM-compliant (well, sort of...)
isDOM = (document.getElementById ? true : false);

function elementFromid(id)
{
 var Element;
 if (isDOM) { Element = document.getElementById(id); }
 else if (isIE ) { Element = document.all[id]; }
 return Element;
}
function get_event_target(e)
{
	if (isIE)
		return e.srcElement;
	else
		return e.target;
}
// get the true offset of anything on NS4, IE4/5 & NS6, even if it's in a table!
function getAbsPos(elt,which) {
 iPos = 0;
 while (elt != null) {
  iPos += elt["offset" + which];
  elt = elt.offsetParent;
 }
 return iPos;
}
function getAbsX(elt) { return (elt.x) ? elt.x : getAbsPos(elt,"Left"); }
function getAbsY(elt) { return (elt.y) ? elt.y : getAbsPos(elt,"Top"); }


function open_href(a, related)
{
	if (a.href.substr(0,10) == 'javascript')
	{
		eval(a.href);
		return true;
	}
	else
	{
		open_url(a.href, related, a.target != undefined && a.target != '') ;
		return true;
	}
}

function click_link(id)
{
	var a = elementFromid(id);
	if (a == undefined)
		return false;

	if (a.onclick != null)
	{
		a.onclick();
		return true;
	}
	else
	{
		open_href(a);
		return true;
	}
}



// handler functions	
function keydown(e) 
{ 
	if (e == undefined) e = window.event; 	var key = (typeof e.which == 'number')?e.which:e.keyCode;
	var fCancel = ARFocusGlobal.keydown(this,key);
	e.cancelBubble = fCancel;	return !fCancel; }

function lookup_list_key_down(e)
{
	if (e == undefined) e = window.event; 	var key = (typeof e.which == 'number')?e.which:e.keyCode;
	var fCancel = false;
	
	switch (key)
	{
		case 13:
		case 32:
			lookup_choose();
			fCancel = true;
			break;
	}
	return !fCancel; }
function lookup_keys_down(e)
{
	if (e == undefined) e = window.event; 	var key = (typeof e.which == 'number')?e.which:e.keyCode;
	var fCancel = false;
	
	switch (key)
	{
		case 27:
			lookup_cancel();
			fCancel = true;
			break;			
	}
	return !fCancel; }


//--------------------------------
// popups - general
//--------------------------------



function set_td_visibility(td, fVisible)
{
	
	if (fVisible)
	{
		if (td.style.visibility != 'visible')
		{
			td.style.visibility = 'visible';
			td.style.display = 'inline';
		}
	}
	else
	{
		if (td.style.visibility != 'hidden')
		{
			td.style.visibility = 'hidden';
			td.style.display = 'none';
		}
	}
}

function div_show(div)
{
	div.parentNode.style.zIndex = 1;
	div.style.visibility = "visible";
	div.style.display = "inline";
}
function div_hide(div)
{
	
	div.style.visibility = "hidden";
	//iframes won't work on ie unless this is included
	//google will complain unless it is not included
	if (isIE)
		div.style.display = "none";
	div.parentNode.style.zIndex = 0;
}

document.onmousedown = checkifstatus;

var fMouseDownCancel  = false;
function checkifstatus()
{
	if (fMouseDownCancel)
		fMouseDownCancel = false;
	else if (window.set_popup != undefined) 
		set_popup(null);
}

//NB this won't work for mousedown as on chrome this stops other evets (such as click)
//use fMouseDownCancel instead
function cancel_bubble(e)
{
	if (e == undefined) e = window.event; 	e.cancelBubble = true;	if (e.stopPropagation) e.stopPropagation();
	return false;	
}


function lookup_cancel()
{
	var choice_form = elementFromid('filter');
	var df = elementFromid('data_form_1');

	if (choice_form != null)
	{
		var id = GetQs(choice_form.action,"field_id");
		var field_but = parent.elementFromid(id + '_but');
		safe_focus(field_but);
	}
	var id = GetQs(df.action,"field_id")
	parent.dd_search[id] = parent.GetWhere(df.action);
	parent.ParentLookupClose(id);
	return true;
}


//--------------------------------
// browse
//--------------------------------

function browse(cid,mode)
{
	var df = elementFromid('data_form_' + cid);
	var rec = get_checked_option(df.table_name);
	var oldqs = get_qs(cid);
	var url = BasePath + '/pages/';
	switch(mode)
	{
		case 'view':
			url += rec.value + '/p1/list.aspx';
			break;
		case 'add':
			if (elementFromid(rec.id + '_access').value.indexOf('I') == -1)
			{
				alert('You do not have access to add a new ' + elementFromid(rec.id + '_title').innerHTML);
				return false;
			}
			url += rec.value + '.aspx?mode=add';
			break;
		case 'search':
			url += rec.value + '/search.aspx';
			break;
	}
	var oldqs = get_qs(cid);
	url = ReplaceQs(url,'from',GetQs(oldqs,'id'));
	goto_page(url);
	return false;
}

//--------------------------------
// sorting
//--------------------------------
function set_sort(cid,column)
{
	var url = get_url(cid);
	url = ReplaceQs(url,'sort',column)
	if (get_select(cid) == 'S')
		url = set_key(url,'');
	else
		url = set_key(url,get_keys(cid));
		
	replace_url(url);
}
//--------------------------------
// paging
//--------------------------------
function change_page(df,pages)
{
	var cid = get_cid(df);
	var page_field = df.page;
	var old_page = parseInt(df.page_o.value);
	var page = parseInt(page_field.value);
	var fGo = true;
	
	if (page < 1)
	{
		alert('You cannot move before the first page.')
		page = 1;
		fGo = false;
	}
	else if (page > pages)
	{
		var msg = 'Only the first ' + pages + ' pages can be shown,\n' +
			'please amend your search to make it more selective.\n';

		fGo = (page <= pages);
	
		if (!fGo) 
		{
			var msg = 'Only the first ' + pages + ' pages can be shown,\n' +
				'please amend your search to make it more selective.\n';
			if (old_page != pages)
			{
				msg = msg + 'Do you wish to go to page ' + pages + ' ?';
				fGo = confirm(msg);
			}
			else
				alert(msg);
			page = pages;
		}
	}
	if (fGo && page != old_page)
		switch_page(page,cid);
	else
		page_field.value = old_page;
	return false;
}
function switch_page(page,cid)
{
	if (page == 0)
		return;
	
	//remove key and replace page number 
	var url = get_url(cid);
	var old_page = get_page(url);
	if (old_page == page)
		return;
		
	url = set_page(url,page);

	if (get_select(cid) == 'S')
		url = set_key(url,'');
	else
		url = set_key(url,get_keys(cid));
		
	replace_url(url);
}
function change_pagesize(df)
{
	var cid = get_cid(df);
	var pagesize_field = df.pagesize;
	var pagesize = pagesize_field.value;
	var old_pagesize = elementFromid('pagesize_o' + cid).value;
	var fGo = false;
	
	if (pagesize < 5)
	{
		alert('Page size cannot be less than 5');
		pagesize = 5;
	}
	else if (pagesize > 40)
	{
		alert('Page size cannot be more than 40');
		pagesize = 40;
	}
	if (pagesize == old_pagesize)
		pagesize_field.value = pagesize;
	else
		set_pagesize(pagesize,cid);
	return false;
}
function set_pagesize(pagesize,cid)
{
	var url = get_url(cid);
	replace_url(set_key(ReplaceQs(url,'pagesize',pagesize),get_keys(cid)));
}
function replace_url(url)
{
	open_url(url,false,false,0,0,0,0,true);
}


//--------------------------------
// row select
//--------------------------------

function select_all_rows(fCheck,cid)
{
	var df = elementFromid('data_form_' + cid);
	for(i = 0; i < df.row.length; i++)
	{
		if (df.row[i].checked != fCheck)
			df.row[i].checked = fCheck;
	}
}
var last_box = null;
function select_row(box)
{
	var df = box.form;
	var cid = get_cid(df);
	var select = get_select(cid);
	if (select == 'S')
	{
		var url = get_url(cid);
		var key = get_key(url);
		if (last_box == null)
		{
			if (key == '')
				last_box = elementFromid('row_0');
			else
				last_box = get_row_from_key(df,key);
		}
		if (last_box == undefined)
			last_box = null;
		else
			set_row_colour(last_box);
		last_box = box;
	}
	set_access(box,select,cid);
	set_row_colour(box);
}

var last_tree = null;
function select_tree_row(option)
{
	var qs = get_qs('1');
	var df = elementFromid('data_form_1');
	if (last_box == null)
	{
		var table = GetQs(qs,'table');
		if (table == '')
			last_tree = df.table_name[0];
		else
			last_tree = elementFromid('tab_' + table);
	}
	last_tree.parentNode.className = '';
	last_tree = option;
	option.parentNode.className = 'selected';
}
function set_access(option,select,cid)
{
	var fAccess = true;
	if (select == 'M')
	{
		var list = get_form_control('row',cid);
		for( var i = 0; i < list.length; i++)
		{
			if (!check_access(list[i]))
			{
				fAccess = false;
				break;
			}
		}
	}
	else
	{
		if (!check_access(option))
			fAccess = false;
	}
	safe_disable('edit_but',!fAccess);
	safe_disable('list_edit_but',!fAccess);
	safe_disable('delete_but',!fAccess);
}
function check_access(option)
{
	if (option.checked)
	{
		var id = option.id;
		var num = get_trailing_number(id);
		var access = elementFromid('rowaccess_' + num);
		if (access != undefined)
		{
			if (access.value == 'false')
				return false;
		}
	}
	return true;
}
function get_rowpage(cid)
{
	var list = get_form_control('row',cid);
	for( var i = 0; i < list.length; i++)
	{
		if (list[i].checked)
		{
			return elementFromid('rowpage_' + get_trailing_number(list[i].id)).value;
		}
	}
}
function get_row_from_key(df,key)
{
	var list = df.row;
	for( var i = 0; i < list.length; i++)
	{
		if (list[i].value == key)
			return list[i];
	}
}
function set_row_colour(radio,newclass)
{
	var tr = radio.parentNode.parentNode;
	var i = parseInt(radio.id.substr(radio.id.indexOf("_") + 1,3)) ;
	if (radio.checked)
		tr.className = 'selected';
	else if (i % 2 == 0)
		tr.className = 'even';
	else
		tr.className = 'odd';
}
function change_select(control)
{
	var df = control.form;
	var cid = get_cid(df);
	var old_select = get_select(cid);
	var new_select = control.value;
	var url = get_url(cid);
	url = ReplaceQs(url,'select',new_select);
	if (old_select == 'M' && new_select == 'S')
		url = set_key(url,get_keys(cid,true));
	else
		url = set_key(url,'');
	replace_url(url);
}

//--------------------------------
// linking and redirection
//--------------------------------

function favourite_search(df)
{
	var url = get_url('1');
	open_url_generic('list.aspx?table=' + get_table(url) + '&' + df.fav_list.value );
	return false;
}
function favourite_open()
{
	open_url(get_checked_option(elementFromid('data_form_1').row).value);
	return false;
}

function confirm_exit()
{
	if (window.all_fields == undefined)
	{
		return true;
	}
	else
	{
		var fExit = !all_fields('1','check_field_changed');

		if (!fExit) fExit = confirm('Do you wish to abandon your changes?');
		return fExit;
	}
}
//function record_link(cid,table,key,parent_key)
//{		
//	var oldqs = get_qs(cid);
//	var url = 'record.aspx?table=' + table + '&key=' + key + '&from=' + GetQs(oldqs,'id');
//	if (parent_key != undefined)
//		if (parent_key != '')
//			url = url + '&child_tab=' + GetQs(oldqs,'table') + '&child_key=' + parent_key;
//	open_url_generic(url,false);
//}
//function record_link(cid,table,key,fPreserveFrom,mode,extra)
//{		
//	var oldqs = get_qs(cid);
//	var url = 'record.aspx?table=' + table + '&key=' + key 
//		+ '&from=';
//	if (fPreserveFrom)
//		url = url + GetQs(oldqs,'from');
//	else
//		url = url + GetQs(oldqs,'id');
//	url = url + AppendQs('mode',mode);
//	
//	if (extra != undefined)
//		if (extra != '')
//			url = url + '&' + extra;
//	open_url_generic(url);
//}
function do_download(cid, url)
{
	if (get_select(cid) == 'M')
	{
		count = get_key_count(cid);
		if (count == 0)
		{
			alert('You must select at least one ' + get_title(cid));
			return false;
		}
	}
	else
	{
		count = get_count(cid);
	}
	if (confirm('Are you sure you wish to download these ' + count + ' ' + get_title(cid,count) + '?'))
	{
		url += AppendQs('cid', cid);
		open_url(url,true,true, 480,830)
	}
	return true;
}
function download_link(cid,columns,sort)
{
	var url = get_url(cid);
	var qs = 'table=' + get_table(url);

	if (get_select(cid) == 'M')
	{
		qs += AppendQs('key',get_keys(cid));
	}
	else
	{
		qs += GetWhere(url,false)
	}
	
	qs += AppendQs('columns',columns);
	qs += AppendQs('sort', sort);
	qs += AppendQs('from', GetQs(url,'from'));

	open_url_generic('download.aspx?' + qs);
	return false;
}	

function related_link(cid,rec_type,mode,key,add_page,copy_rec)
{
	var url;
	var old_url = get_url(cid);
	var key_count;

	if (key != undefined && key != '')
		key_count = 1;
	else
		key_count = get_key_count(cid);
	

	if (mode != 'view' && mode != 'add' || copy_rec)
	{
		if (key_count == 0)
		{
			alert('You must select at least one ' + get_title(cid));
			return false;
		}
	}

	if (rec_type == '')
	{
		if (mode == 'delete')
		{
			if (get_select(cid) == 'M')
				rec_type = 'list';
			else
				rec_type = 'record';
		}
		else
		{
			rec_type = 'record';
		}
	}
	var fOk = true;
	if (mode == 'delete')
	{
		if (key_count == 1)
			fOk = check_delete(cid);
		else
			fOk = confirm('Are you sure you wish to delete these ' + key_count + ' ' + get_title(cid,key_count) + '?');
	}
	if (mode == 'edit' && get_select(cid) == 'A')
	{
		if (key_count > 1)
			fOk = confirm('Are you sure you wish to edit these ' + key_count + ' ' + get_title(cid,key_count) + '?');
	}
	if (!fOk) return false;
	
	var url = BasePath + '/pages/';
	var table = get_table(old_url);
	var qs = '';
	var page = '';
	
	if (key == undefined)
		key = get_keys(cid);

	if (add_page)
		page = get_rowpage(cid);
		
	switch (rec_type)
	{
		case 'record':
			url += table + '.aspx';
			if (mode != 'view') qs += AppendQs('mode',mode);
			if (page != '') qs += AppendQs('page',page);
			if (copy_rec) qs += AppendQs('copy', get_keys(cid));
			break;
		case 'list':
			url += table + '/';
			if (page != '') url += 'p' + page + '/';
			url += 'list.aspx';
			if (mode != 'view') qs += AppendQs('mode',mode);
			break;
		case 'search':
			url += table + '/search.aspx';
			break;
	}	

	if (!copy_rec && mode != 'edit' && mode != 'delete' || get_select(cid) == 'A')
	{
		//qs += GetWhere(old_url,  mode == 'add');
		qs += GetWhere(old_url);
	}

	qs += AddQs('sort',old_url);
	qs += '&from=' + GetQs(old_url,'id');
	if (qs != '') url += '?' + qs.substring(1);
	if (mode != 'add') 
		url = set_key(url,key);
		
	open_url(url);
	return false;
}
function check_delete(cid)
{
	return confirm('Are you sure you wish to delete the selected ' + get_title(cid) + ' ?');
}

var fOpening = false;
var sub_window = null;

function do_unload()
{
	// close all child windows 
	sub_window_close();
	admin_window_close();
}
function sub_window_close()
{
	if (child_window_open(sub_window)) 
	{
		sub_window.close();
		sub_window = null;
		return true;
	}
	return false;
}
function admin_window_close()
{
	if (child_window_open(admin_child)) 
	{
		admin_child.close();
		admin_child = null;
		return true;
	}
	return false;

}
function child_window_open(win)
{
	if (win == null)
		return false;
	else if (win.closed)
		return false
	else
		return true;
}

function open_with_field(url,id)
{
	  var field = elementFromid(id);
	  open_url(ReplaceQs(url,'ff_' + get_stem(field.name),get_field_value(field)));
}

function open_url_generic(page,related,height,width,left,top)
{
	open_url(AppPath + '/generic/pages/' + page,related,false,height,width,left,top);
}

//height unspecified or 0 = default size
// height -1  = max size



function open_url(url,related,popup,height,width,left,top, fReplace)
{
	var fOk = true;
	var options = '';
	url = add_preserve(url);
	

	if (related)
	{
		if (child_window_open(sub_window))
		{
			sub_window.focus();
			sub_window.alert('Window already open. You must close this window first');
			fOk = false;
		}
		else
		{
			popup = true;
			options = 'dependent=yes';
		}
	}

	if (fOk && popup)
	{
		if (!related)
		{
			options = 'menubar=yes,toolbar=yes,status=yes,location=yes';
		}
		var new_window;

		if (fOk)
		{
			options = options + ',alwaysRaised=yes,resizable=yes,scrollbars=yes';
			if (height == undefined)
			{
				height = screen.availHeight - 50;
				width = screen.availWidth - 50;
				left = '0';
				top = '0';
			}
			else if (left == undefined)
			{
				top = (screen.availHeight -50 - height) / 2;
				left = (screen.availWidth - 50 - width) / 2;
			}
			
			if (height > 0 && height != undefined)
			{
				options = options + AppendAttrib('height',height)
								+ AppendAttrib('width',width)
								+ AppendAttrib('left',left)
								+ AppendAttrib('top',top);
			
			}
			new_window = window.open(url, '', options);
			if (new_window == null)
			{
				alert('You must enable popups for this site to work correctly. This site includes no popup advertising.');
				fOk = false;
			}
		}
		if (fOk)
		{
			if (related)
			{
				sub_window = new_window;
			}
		}
	}
	if (fOk && !popup && !fOpening) 
	{
		var page_name = GetPageName(url);
		if ( page_name == 'file')
		{
			goto_page(url);
			fOk = false;
		}
		else
		{
			var old_url = get_url('1');
			if (old_url == '')
			{
				fOk = true;
			}
			else
			{
				var mode = get_mode(old_url);
				if (GetPageName(old_url) != 'login' && (mode == 'edit' || mode == 'add'))
				fOk = confirm_exit();
			}
		}			
		if (fOk)
		{
			fOpening = true;
			goto_page(url,fReplace);
		}
	}
}
function add_preserve(url)
{
	if (window.preserve_qs != undefined)
	{
		var preserves = preserve_qs.split('&');
		var i,param;
		for (i=0; i < preserves.length; i++)
		{
			param = preserves[i].split('=');
			var paramloc = findparam(url, param[0], '&', '=');
			if (paramloc[1] == -1)
				url = ReplaceQs(url,param[0],param[1]);
		}
	}
	return url;
}
function goto_page(url,fReplace)
{
	if (isIE)
		url = url.replace(/&/g,'&amp;',true);
	if (fReplace)
		window.location.replace(url);
	else
		window.location.href = url;
}

function close_child()
{
	if (confirm_exit())
	{
		var df = elementFromid('data_form_1');
		if (df != null)
		{
			// this may fail with an access error
			try
			{ 
				return window.opener.ChildWindowClosing(GetQs(df.action,"field_id"));
			} catch (e) { };
		}
		else
			return true;
			
	}
	return false;
}
function ChildWindowClosing(id)
{
	if (sub_window_close())
	{
		var field = elementFromid(id);
		set_field_focus(field);
		return true;
	}
}
function set_field_focus(field)
{
	if (field != null)
	{
		field = focus_control(field);

		if (field != null)
		{
			if (!field.disabled)
			{
				//var base_field = get_base_field(field);
				//var field_type = get_field_type(base_field);
				safe_focus(field);
				//if (field_type == 'ajax')
				//	cmb_focus(base_field.id);
			}
		}
	}
}
var focus_field = null;

function MCE_setup(ed)
{
    tinymce.dom.Event.add(ed.getWin(), 'focus', MCE_event);
    tinymce.dom.Event.add(ed.getWin(), 'blur', MCE_event);
}

function MCE_event(e)
{
 	if( !e ) var e = window.event;
	if (e.type == 'blur' || e.type == 'focus')
	{
		var ed = tinyMCE.selectedInstance;
		var field = elementFromid(ed.id);
		if (e.type == 'blur')
		{
			ed.save();
			if (field.value == '<p>' + nbsp + '</p>') field.value = '';
			on_field_blur(field);
		}
		else
			on_field_focus(field);
	}
}

//function MCE_save(element_id, html, body)
//{
	// Do some custom HTML cleanup
	//html = html.replace(/a/g,'b');
//	if (html == '<p>&nbsp;</p>') html = '';
//	return html;
//}

function on_field_focus(field)
{
	// validate field
	if (window.validate_last_field !== undefined) validate_last_field(field);

	focus_field = field;
	if (field.offsetParent != null)
		field.offsetParent.id = 'focus';	
}
function on_field_blur(field)
{
	// validate field
	if (window.validate_last_field !== undefined) validate_last_field(field);

	if (field.offsetParent != null)
		field.offsetParent.id = '';	
}

function open_url_previous()
{
	var url;
	url = elementFromid('url_previous');
	//old method can be removed later
	if (url == null)
		url = elementFromid('url_previous1');
	
	if (url != null)
	{
		open_url(url.value);
		return true;
	}
}

function cancel_edit()
{
	if (!open_url_previous())
	{
		if (window.opener != undefined)
		{
			if (close_child()) window.close();
		}
		else
		{
			related_link('1','record');
		}
	}
}

//--------------------------------
// field highlighting
//--------------------------------

function get_form_control(name,cid)
{
	var df = elementFromid('data_form_' + cid);
	if (df != null)
	{
		var control = df[name];
		if (control != undefined)
			return control;
	}
	return null;
}

function get_key_count(cid)
{
	var count = 0;
	var list = get_form_control('row',cid);
	var fNoList = false;
	
	if (list == null) 
		fNoList = true;
	else if (list.length == undefined)
		fNoList = true;
		
	if (fNoList)
	{
		var qs = get_qs(cid);
		var key = new String(GetQs(qs,'key'));
		var i = 0;
		while (true)
		{
			i = key.indexOf(',',i + 1)
			count++;
			if (i < 0) break;
		}
	}
	else
	{
		if (get_select(cid) == 'A')
			count = get_count(cid);
		else
		{
			for( var i = 0; i < list.length; i++)
			{
				if (list[i].checked)
					count++;
			}
		}
	}		
	return count;
}

function row_key(i)
{
	var row = elementFromid('row_' + i);
	if (row == undefined)
		return NULL_VALUE;
	else
		return row.value;
}

//function toggle_dropped(row)
//{
//	var div = elementFromid('dropped_div' + row);
//	var toggle = elementFromid('toggle_' + row);
//	if (div.style.visibility == 'visible')
//	{
//		div_hide(div);
//		toggle.src = toggle.src.replace(/contract/,'expand');
//	}
//	else
//	{
//		div_show(div);
//		toggle.src = toggle.src.replace(/expand/,'contract');
//	}
//}

function get_keys(cid,fSingleKeyOnly)
{
	if (get_select(cid) == 'A')
		return '';

	var list = get_form_control('row',cid);

	if (list == null )
		return get_key(get_url(cid));

	var sKeys = '';
	if (list.length == undefined)
		sKeys = list.value;
	else
	{
		for( var i = 0; i < list.length; i++)
		{
			if (list[i].checked)
			{
				if (sKeys != '') sKeys = sKeys + ',';
				sKeys = sKeys + list[i].value;
				if (fSingleKeyOnly) break;
			}
		}
	}
	return sKeys;
}

function get_cid(df)
{
	return get_trailing_number(df.id);
}
function get_page(url)
{
	var i,j;
	i = url.indexOf('/list.aspx');
	if (url.substr(BasePath.length,7) == '/pages/' && i != -1)
	{
		j = url.indexOfRev('/',i-1);
		return url.substring(j+2,i);
	}
	else
		return GetQs(url,'page');
}
function set_page(url,page)
{
	var i,j;
	i = url.indexOf('/list.aspx');
	if (url.substr(BasePath.length,7) == '/pages/' && i != -1)
	{
		j = url.indexOfRev('/',i-1);
		return url.substring(0,j+2) + page + url.substring(i);
	}
	return ReplaceQs(url,'page',page);
}
function get_count(cid)
{
	return elementFromid('count_' + cid).value;
}

function get_key(url)
{
	var t = url.substring(BasePath.length+1,url.indexOf('.aspx')).split('/');
	if (t[0] == 'pages' && t.length == 3 )
	{
		if (t[2] != 'list' && t[2] != 'record')
		{
			return t[1];
		}
	}
	return GetQs(url,'key');
}

function set_key(url,key)
{
	var t = url.substring(BasePath.length+1,url.indexOf('.aspx')).split('/');
	
	if (t[0] == 'pages' && t.length == 3 )
	{
		if (t[2] != 'list' && t[2] != 'record')
		{
			if (key == '')
				return url.replace('/' + t[1] + '/', '/');
			else
			{
				if (key.indexOf(',') == -1)
					return url.replace('/' + t[1] + '/','/' + key + '/');
				else 
					url = url.replace('/' + t[1] + '/','/');
			}
		}
	}
	return ReplaceQs(url,'key',key);
}

function get_table(url)
{
	var i,j;
	var t = url.substring(BasePath.length+1,url.indexOf('.aspx')).split('/');
	if (t[0] == 'pages')
	{
		if (t[t.length-1] == 'list' || t[t.length-1] == 'search')
			return t[1];
		else
			return t[t.length-1];
	}	
	return GetQs(url,'table');	
}

function get_url(cid)
{
	var df = elementFromid('data_form_' + cid);
	if (df == null)
		return '';
	var url;
	url = df.action;

	//skip http(s):	
	if (url.startsWith('http://'))
		url = url.substring(7);
	else if (url.startsWith('https://'))
		url = url.substring(8);
		
	//skip website name and basepath
	if (url.startsWith(window.location.host))
	{
		url = url.substring(window.location.host.length);
	}
	return url;

//	var field = elementFromid('url' + cid)
//	if (field == null)
//		return '';
//	else
//		return field.value;	
}
function get_qs(cid)
{
	var url = get_url(cid);
	if (url == '')
		return '';
	else
		return url.substring(url.indexOf('?') + 1,500);
}
function get_title(cid,Count)
{
	var field;
	if (Count != undefined && Count > 1)
		field = elementFromid('title_plural_' + cid);
	else
		field = elementFromid('title_' + cid);
	if (field != undefined)
		return field.value;
}
function get_mode(url)
{
	var page_name = GetPageName(url);
	var mode;
	if (page_name == 'search') 
		mode = 'search';
	else if (page_name == 'upload') 
		mode = 'add';
	else
	{
		mode = GetQs(url,'mode');
		if (mode == '') mode = 'view';
	}
	return mode;
}

function get_select(cid)
{
	var select = GetQs(get_qs(cid),'select');
	if (select == '') select = 'S';
	return select;
}		
function get_select_value(field)
{
	if (field.type == 'select-multiple')
		return get_multi_select_value(field);
	if (field.selectedIndex == -1)
		return '';
	else
		return field.value;
}

function get_select_text(field)
{
	if (field.type == 'select-multiple')
		return get_multi_select_text(field);
	else
		return field.options[field.selectedIndex].text;
}
function get_multi_select_value(field,fAll)
{
	var value = '';
	for(var i = 0; i < field.options.length; i++)
	{
		if (fAll || field.options[i].selected)
		{
			if (value != '') value = value + ',';
			value = value + field.options[i].value;
		}
	}
	return value;
}
function get_multi_first_select_value(field)
{
	for(var i = 0; i < field.options.length; i++)
	{
		if (field.options[i].selected)
		{
			return field.options[i].value;
		}
	}
	return NULL_VALUE;
}

function get_multi_select_text(field)
{
	var value = '';
	for(var i = 0; i < field.options.length; i++)
	{
		if (field.options[i].selected)
		{
			if (value != '') value = value + '|';
			value = value + field.options[i].text;
		}
	}
	return value;
}
function get_select_text_from_value(field, value)
{
	var i = get_select_index_from_value(field, value);
	if (i == -1)
		return '';
	return field.options[i].text;
}
function get_select_index_from_value(field, value)
{
	for(var i = 0; i < field.options.length; i++)
	{
		if (field.options[i].value == value)
			return i;
	}
	return -1;
}
function set_multi_select_value(select,value)
{
	var i;
	for(i = 0; i < select.options.length; i++)
	{
		if (select.options[i].value == value)
			select.options[i].selected = true;
		else
			select.options[i].selected = false;
	}
}


function multi_delete_all(sel)
{
	for(var i = sel.options.length - 1; i >= 0; i--)
	{
		if (sel.options[i].value != NULL_VALUE)
			sel.options[i] = null;
	}
	if ( sel.options.length == 0)
		sel.size = 1;
	else
		sel.size = sel.options.length;
}

function add_select_items(field,value,text)
{
	var i;
	var j = 0;
	var k;
	var l = 0;

	var a = new String();
	while(true)
	{
		i = value.indexOf(',',j);
		if (i == -1) i = value.length;
		k = text.indexOf('|',l);
		if (k == -1) k = text.length;
		add_select_item(field, value.substring(i,j), text.substring(k,l));
		j = i + 1;
		l = k + 1;
		if (j >= value.length) break;
	}
	var b = new String();
	
}
function collation_ascii(value)
{
	var i, code;
	var coll_value = new String();
	for(i = 0; i < value.length; i++)
	{
	    code = value.charCodeAt(i);
	    
        //above zero and below 'a' - move about
        if (code >= 48 && code <= 96)
        {
            if (code <= 57)
            {
                //0-9 now starts at 87 through to 96
                code += 87 - 48;
            }
            else
            {
                //everything else moves down 10
                code -= 10;
            }
        }
        coll_value += String.fromCharCode(code);
	}
	return coll_value;
}

function locate_select_item(field,value,text)
{
	var i;
	//locate correct position
	for(i = 0; i < field.options.length; i++)
	{
		if (field.options[i].text.charAt(0) != '[')
		{
			if (field.options[i].value == value) return -1;
			if (collation_ascii(field.options[i].text.toUpperCase()) > collation_ascii(text.toUpperCase()))
				break;
		}
	}
	return i;
}

function add_select_item(field,value,text)
{
	var i = locate_select_item(field,value,text);
	if (i == -1) return;
	
	//add new option
	var new_option = add_select_option(field.options,i,value,text);
	field.style.width = '';
	
	if (field.type == 'select-multiple')
	{
		new_option.selected = true;
		field.size = field.options.length;
	}

}
function add_select_option(options, i, value, text)
{
	//add new option
	options[options.length] = new Option('','');
	var j;
	//move options up
	for (j = options.length-2; j >= i; j--)
	{
		options[j+1].value = options[j].value;
		options[j+1].text = options[j].text;
		options[j+1].selected = options[j].selected;
	}
	
	options[i].value = value;
	options[i].text = text;
	return options[i];
}
function select_all_options(options)
{
	for (var i = 0; i < options.length; i++)
	{
		options[i].selected = true;
	}
}	

function get_checked_option(field)
{
	//not an array
	if (field.length == undefined)
		return field;
		
	for(var i = 0; i < field.length; i++)
	{
		if (field[i].checked)
			return field[i];
	}
	return field[0];
}
function option_from_value(options,value,iStart,iEnd)
{
	if (iStart == undefined) iStart = 0;
	if (iEnd == undefined) iEnd = options.length;
	
	for(var i = iStart; i < iEnd; i++)
	{
		if (options[i].value == value)
			return options[i];
	}
	return null;
}

/*
   The following code is Copyright (C) Simon Willison 2004.

   document.getElementsBySelector(selector)
   - returns an array of element objects from the current document
     matching the CSS selector. Selectors can contain element names, 
     class names and ids and can be nested. For example:
     
       elements = document.getElementsBySelect('div#main p a.external')
     
     Will return an array of all 'a' elements with 'external' in their 
     class attribute that are contained inside 'p' elements that are 
     contained inside the 'div' element which has id="main"

   New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
   See http://www.w3.org/TR/css3-selectors/#attribute-selectors

   Version 0.4 - Simon Willison, March 25th 2003
   -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
   -- Opera 7 fails 
*/

function getAllChildren(e) {
  // Returns all children of element. Workaround required for IE5/Windows. Ugh.
  return e.all ? e.all : e.getElementsByTagName('*');
}

document.getElementsBySelector = function(selector) {
  // Attempt to fail gracefully in lesser browsers
  if (!document.getElementsByTagName) {
    return new Array();
  }
  // Split selector in to tokens
  var tokens = selector.split(' ');
  var currentContext = new Array(document);
  for (var i = 0; i < tokens.length; i++) {
    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
    if (token.indexOf('#') > -1) {
      // Token is an ID selector
      var bits = token.split('#');
      var tagName = bits[0];
      var id = bits[1];
      var element = document.getElementById(id);
      if (tagName && element.nodeName.toLowerCase() != tagName) {
        // tag with that ID not found, return false
        return new Array();
      }
      // Set currentContext to contain just this element
      currentContext = new Array(element);
      continue; // Skip to next token
    }
    if (token.indexOf('.') > -1) {
      // Token contains a class selector
      var bits = token.split('.');
      var tagName = bits[0];
      var className = bits[1];
      if (!tagName) {
        tagName = '*';
      }
      // Get elements matching tag, filter them for class selector
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      continue; // Skip to next token
    }
    // Code to deal with attribute selectors
    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
      var tagName = RegExp.$1;
      var attrName = RegExp.$2;
      var attrOperator = RegExp.$3;
      var attrValue = RegExp.$4;
      if (!tagName) {
        tagName = '*';
      }
      // Grab all of the tagName elements within current context
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      var checkFunction; // This function will be used to filter the elements
      switch (attrOperator) {
        case '=': // Equality
          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
          break;
        case '~': // Match one of space seperated words 
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
          break;
        case '|': // Match start with value followed by optional hyphen
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
          break;
        case '^': // Match starts with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
          break;
        case '$': // Match ends with value - fails with "Warning" in Opera 7
          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
          break;
        case '*': // Match ends with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
          break;
        default :
          // Just test for existence of attribute
          checkFunction = function(e) { return e.getAttribute(attrName); };
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (checkFunction(found[k])) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
      continue; // Skip to next token
    }
    
    if (!currentContext[0]){
    	return;
    }
    
    // If we get here, token is JUST an element (not a class or ID selector)
    tagName = token;
    var found = new Array;
    var foundCount = 0;
    for (var h = 0; h < currentContext.length; h++) {
      var elements = currentContext[h].getElementsByTagName(tagName);
      for (var j = 0; j < elements.length; j++) {
        found[foundCount++] = elements[j];
      }
    }
    currentContext = found;
  }
  return currentContext;
}
function format_number(num,places)
{
	var text = new String(num);
	for(var i = 0;i < places - text.length; i ++)
	{
		text = '0' + text;
	}
	return text;
}

// date 
function date_from_str(sDate)
{
	var sSplit = sDate.split('-');	
	return new Date(Number(sSplit[0]), Number(sSplit[1]) - 1, Number(sSplit[2]));
}
function new_date(y,m,d)
{
	var datDate = new Date();
	if (m < 1)
	{
		m = 12;
		y -= 1;
	}
	if (m > 12)
	{
		m = 1;
		y += 1;
	}
	datDate.setDate(1);
	datDate.setFullYear(y);
	datDate.setMonth(m - 1);
	datDate.setDate(d);
	return datDate;
}

function date_from_mask(strText,FormatMask)
{
	var DateParts = new Array();

	dateparts_from_mask(strText,FormatMask,DateParts);
	var NewDate = new Date(DateParts[0], DateParts[1] - 1, DateParts[2], DateParts[3], DateParts[4], DateParts[5]);

	return NewDate;	
}
function datepart_from_mask(text,mask,part)
{
	i = mask.indexOf(part);
	if (i >= 0)
		return text.substring(i, i + part.length);
	else
		return null;
}

function dateparts_from_mask(strText,mask,DateParts)
{
	var i,CheckDate;
	CheckDate = false;
	
	DateParts[0] = datepart_from_mask(strText, mask,'yyyy');
	if (DateParts[0] != null)
	{
		CheckDate = true;
	}
	else
	{
		DateParts[0] = datepart_from_mask(strText, mask,'yy');
		if (DateParts[0] != null)
		{
			CheckDate = true;
			DateParts[0] += 2000 
		}
		else
			DateParts[0] = 1900;
	}
	DateParts[1] = datepart_from_mask(strText, mask,'MM');
	if (DateParts[1] != null)
		CheckDate = true;

	DateParts[2] = datepart_from_mask(strText, mask,'dd');
	if (DateParts[2] != null) CheckDate = true;

	DateParts[3] = datepart_from_mask(strText, mask,'HH');
	if (DateParts[3] != null)
		CheckDate = true;
	else
		DateParts[3] = 0;

	DateParts[4] = datepart_from_mask(strText, mask,'nn');
	if (DateParts[4] != null) 
		CheckDate = true;
	else
		DateParts[4] = 0;

	DateParts[5] = datepart_from_mask(strText, mask, 'ss');
	if (DateParts[5] != null) 
		CheckDate = true;
	else
		DateParts[5] = 0;

	return CheckDate;
}

/* extra string functions */

String.prototype.left = function (n)
{
	if (n <= 0)
	    return '';
	else 
		return this.substring(0,n);
}

String.prototype.right = function (n)
{
    if (n <= 0)
       return '';
    else 
		return this.substring(this.length, this.length-n);
}
String.prototype.startsWith = function (s)
{
	return this.left(s.length) == s;
}

String.prototype.endsWith = function (s)
{
	return this.right(s.length) == s;
}

String.prototype.removeEnd = function (n)
{
	return this.left(this.length - n);
}
String.prototype.indexOfEnd = function (c,n)
{
	var i = this.indexOf(c,n);
	if (i == 0) i = this.length;
	return i;
}
String.prototype.indexOfRev = function (c,n)
{
	if (n == undefined)	n = this.length-1;
		
	//get stem
	for (; n > -1;n--)
	{
		if (this.charAt(n) == c) break;
	}
	return n;
}
String.prototype.split_any = function(s)
{
	var i,j,k,c, oArray = [];
	k = 1;
	for (i = 0; i < this.length; i++)
	{
		c = this.charAt(i);
		for (j = 0; j < s.length; j++)
		{
			if (c == s.charAt(j))
			{
				k +=1;
				break;
			}
		}			
		if (c != s.charAt(j))
		{
			if (k > oArray.length)
			{
				oArray.length = k ;
				oArray[k-1] = '';
			}
			oArray[k-1] += c;
		}
	}
	return oArray;
}
String.prototype.concat = function (sAdd,sSep)
{
	if (this.length == 0)
		return sAdd;
	if (sAdd == '')
		return this;
	return this + sSep + sAdd;
}
String.prototype.trim = function ()
{
  // Remove leading spaces and carriage returns
	var check,i,s;
	s = this;
	for(i = 0; i < s.length; i++)
	{
		check = s.charAt(i);
		if ( check != '\n' && check != '\r' && check != ' ')
			break
	}  
	if (i > 0)
		s = s.substring(i,s.length);
	
	for(i = s.length - 1; i >= 0; i--)
	{
		check = s.charAt(i);
		if ( check != '\n' && check != '\r' && check != ' ')
			break
	}  
	if (i < s.length - 1)
	{
		s = s.substring(0,i + 1);
	}
	return s;
}
Number.prototype.toHexByte = function ()
{   
	var value = this.toString(16).toUpperCase();
	if (this < 16) value = '0' + value;
	return value;   
}

function get_trailing_number(id)
{
	var i = id.indexOfRev('_');
	if (i == -1) return '';

	return id.substring(i+1);
}
function get_stem(id)
{
	return id.left(id.indexOfRev('_'));
}

function is_positive_integer(value)
{
  	var num = '1234567890';
  	for(var i = 0; i < value.length; i++)
  	{
  		if (num.indexOf(value.charAt(i)) == -1)
  		{
  			return false;
  		}
  	}
  	return true;
}

function add_cid(cid,name)
{
	if (cid != '1') name += cid;
	return name;
}
