var slideSpeed = 20;
var slideInterval = 0;

var currentPage = null;
var currentDialog = null;
var currentWidth = 0;
var currentHash = location.hash;
var hashPrefix = "#_";
var pageHistory = [];
var newPageCount = 0;
var checkTimer;

function CountChildren(row)
{
	if (row.hasChildNodes())
	{
	var child = row.firstChild;
	var num_children = 0;
		while (child)
		{
			if (child.nodeType == 1)
				num_children++;

			child = child.nextSibling;
		}
		return num_children;
	}
	else return 0;
}

// text is always loaded into attributes array FIRST
// this function therefore always converts either to or from this array to whatever else we require
// direction specifies where the text is going
function NormaliseText(txt, direction)
{
//	alert(txt+' dir: '+direction);
	if (typeof txt === "undefined")
		return "";

	switch (direction)
	{
	case 'html': 	text = txt.replace(/&#10;/gi, "<br />");
					text = text.replace(/\"/gi, "&quot;");
				//	text = autoHTML(text, 'target="_blank" onclick="gHandleClicked=true;"');
					break;

	case 'opml':	text = txt.replace(/&/g, "&amp;");					// dumping text from edit box to attributes obj
					text = text.replace(/\"/g, "&quot;");
					text = text.replace(/\n/g, "&#10;");
					text = text.replace(/</g, "&lt;");
					text = text.replace(/>/g, "&gt;");
					break;

	case 'opml2attr':
//					text = txt.replace(/&/g, "&amp;");					// dumping text from opml to attributes obj
					text = txt.replace(/&#38;/g, "&amp;");				// these would have got expanded by the XML parser,
					text = text.replace(/\"/g, "&quot;");				// so re-encode them
					text = text.replace(/\n/g, "&#10;");				
					text = text.replace(/</g, "&lt;");
					text = text.replace(/>/g, "&gt;");
					break;

	case 'edit':	text = txt.replace(/&#10;/g, "\n");					// loading text from atributes to edit box
					text = text.replace(/&quot;/g, "\"");
					text = text.unescapeHTML();
				//	text = text.replace(/&/g, "&amp;");
					break;
	}

	return text;
}

function nl2br(txt)
{
	txt = txt.replace(/\r\n/g, "&#10;");
	txt = txt.replace(/\r/g, "&#10;");
	txt = txt.replace(/\n/g, "&#10;");

	return txt;
}

function autoHTML(strSrc, optAtt)
{
	strSrc = strSrc.replace(/&quot;/gi, '#z#zz#s#a###v#');			// replace " with 8 hashes, definitely not allowed in email addresses and urls :)

	strSrc = strSrc.replace(/(https:\/\/|http:\/\/|ftp:\/\/|www.)([a-zA-Z0-9_?.#-\/&%+=;]*)/gi, '<a href="$1//$2" ' + optAtt + '>$1$2</a>');
	strSrc = strSrc.replace(/www.\/\//gi, 'http://www.');
	
	strSrc = strSrc.replace(/[\s]*([^\s]*@[^\s]*)/gi,' <a href="mailto:$1">$1</a>');

	strSrc = strSrc.replace(/#z#zz#s#a###v#/gi, '&quot;');
	return strSrc;
}

function initStatLyr()
{
	// args: id, left, top, w, h, duration of glide to location onscroll, acceleration factor
	// acceleration factor should be -1 to 1. -1 is full deceleration

var x = document.getElementById('edit-box').offsetLeft;
var y = 0; // document.getElementById('edit-box').offsetTop - 100;
var statLyr = new Glider("edit-box",x,y,null,null,1000,-1,GliderLimiter);

	statLyr.show();
}

function GliderLimiter(destY)
{
//var y1 = document.getElementById('outliner').offsetTop;
var y1 = document.getElementById('main-content').offsetTop + 43;
var h1 = document.getElementById('outliner').offsetHeight;
var h2 = document.getElementById('edit-box').offsetHeight;
var y2 = y1 + h1 - h2;

	if (y2 < y1)
		y2 = y1;

	if (destY < y1)
		return y1;

	if (destY > y2)
		return y2;

	return destY;
}

function Set_Cookie( name, value, expires, path, domain, secure ) 
{
// set time, it's in milliseconds
var today = new Date();
today.setTime( today.getTime() );

/*
if the expires variable is set, make the correct 
expires time, the current script below will set 
it for x number of days, to make it for hours, 
delete * 24, for minutes, delete * 60 * 24
*/
if ( expires )
{
expires = expires * 1000 * 60 * 60 * 24;
}
var expires_date = new Date( today.getTime() + (expires) );

document.cookie = name + "=" +escape( value ) +
( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + 
( ( path ) ? ";path=" + path : "" ) + 
( ( domain ) ? ";domain=" + domain : "" ) +
( ( secure ) ? ";secure" : "" );
}

// this function gets the cookie, if it exists
function Get_Cookie( name ) {
	
var start = document.cookie.indexOf( name + "=" );
var len = start + name.length + 1;
if ( ( !start ) &&
( name != document.cookie.substring( 0, name.length ) ) )
{
return null;
}
if ( start == -1 ) return null;
var end = document.cookie.indexOf( ";", len );
if ( end == -1 ) end = document.cookie.length;
return unescape( document.cookie.substring( len, end ) );
}

// this deletes the cookie when called
function Delete_Cookie( name, path, domain ) {
if ( Get_Cookie( name ) ) document.cookie = name + "=" +
( ( path ) ? ";path=" + path : "") +
( ( domain ) ? ";domain=" + domain : "" ) +
";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}

function ScrollToAndFlash(div)
{
	new Effect.ScrollTo(div); Effect.Pulsate(div,{from:0.3, pulses:3});
}

function HasClass(p_element, p_class)
{
	if (p_element.className)
	{
		l_classes = new Array();
		l_classes = p_element.className.split(' ');
		for (var i = 0; i < l_classes.length; i++)
			if (l_classes[i] == p_class)
				return true;
	}
	return false;
}

function AddClass(p_element, p_class)
{
	if (!p_element.className)
		p_element.className = p_class;
	else
	{
		l_classes = new Array();
		l_classes = p_element.className.split(' ');
		for (var i = 0; i < l_classes.length; i++)
			if (l_classes[i] == p_class)
				return;
		p_element.className += ' ' + p_class;
	}
}

function RemoveClass(p_element, p_class)
{
	if (p_element.className)
	{
		l_classes = new Array();
		l_classes = p_element.className.split(' ');
		for (var i = 0; i < l_classes.length; i++)
			if (l_classes[i] == p_class)
				l_classes.splice(i, 1);
		p_element.className = l_classes.join(' ');
	}
}

function getElementsByClassName(className, tag, elm)
{
	var testClass = new RegExp("(^|\\s)" + className + "(\\s|$)");
	var tag = tag || "*";
	var elm = elm || document;
	var elements = (tag == "*" && elm.all)? elm.all : elm.getElementsByTagName(tag);
	var returnElements = [];
	var current;
	var length = elements.length;
	for(var i=0; i<length; i++)
	{
		current = elements[i];
		if(testClass.test(current.className)){
			returnElements.push(current);
		}
	}
	return returnElements;
}

function isElementVisible(e)		    //returns true is should be visible to user.
{
	if (typeof e == "string")
		e = xGetElementById(e);

	while (e.nodeName.toLowerCase() != 'body' && e.style.display.toLowerCase() != 'none' && e.style.visibility.toLowerCase() != 'hidden')
	    e = e.parentNode;
	
	if (e.nodeName.toLowerCase() == 'body')
	    return true;
	else return false;
}

function CheckOrientAndLocation()
{
    if (window.innerWidth != gCurrentWidth)
    {
        gCurrentWidth = window.innerWidth;

        var orient = gCurrentWidth == 320 ? "profile" : "landscape";
        document.body.setAttribute("orient", orient);
    }
}

/*
// this positions the insertion point at the end of the text
// it doesn't happen automatically in Safari
// we call this function when we place focus on the textarea
function SetCaretPositionToEnd(txtarea_id)
{	
	txtarea = document.getElementById(txtarea_id);
	pos = txtarea.innerHTML.length;

	if(txtarea.setSelectionRange)
	{
		txtarea.focus();
		txtarea.setSelectionRange(pos,pos);
	}
	else if (txtarea.createTextRange)
	{
		var range = txtarea.createTextRange();
		range.collapse(true);
		range.moveEnd('character', pos);
		range.moveStart('character', pos);
		range.select();
	}
}
*/

// this positions the insertion point at the end of the text
// it doesn't happen automatically in Safari
// we call this function when we place focus on the textarea
// position:	can take 2 values, 'start', 'end'
function SetCaretPosition(txtarea_id, position)
{
	txtarea = document.getElementById(txtarea_id);
	if (position == 'start')
		pos = 0;
	else pos = txtarea.innerHTML.length;

	if (txtarea.setSelectionRange)
	{
		txtarea.focus();
		txtarea.setSelectionRange(pos,pos);
	}
	else if (txtarea.createTextRange)
	{
		var range = txtarea.createTextRange();
		range.collapse(true);
		range.moveEnd('character', pos);
		range.moveStart('character', pos);
		range.select();
	}
}

function getCaretPos(oField)
{
alert(oField.selectionStart);
	var iCaretPos = 0;
	if (Prototype.Browser.IE)
	{
		var oSel = document.selection.createRange ();
		oSel.moveStart ('character', -oField.value.length);
		iCaretPos = oSel.text.length;
	}
	else iCaretPos = oField.selectionEnd;

	return iCaretPos;
}

var disable_click = true;

HandleMouseClick=function(e)
{
	var target = (e && e.target) || (event && event.srcElement);

	var import_link = document.getElementById('import');
	var import_box = document.getElementById('import-box');
	var edit_box = document.getElementById('edit-box');
	var outliner = document.getElementById('outliner');
	var toolbar = document.getElementById('toolbar');
	var print_options = document.getElementById('print-options');
	var print_options_link = document.getElementById('meta-print');
	var calendar_div = document.getElementById("calendar-div");
	var row_file_bubble = document.getElementById("row-file-bubble");
	
	try
	{
		if (lsclient.IsUserInteractionEnabled() == true)
		{
			if (calendar_div && !isDecendant(target, calendar_div))
				HideCalendar();
			
			if (row_file_bubble.style.display == 'block' && !isDecendant(target, row_file_bubble) && !HasClass(target, 'attachment-clip'))
				lsclient.HideFileBubbleAtRow();
	
			if (import_box.style.display == 'block' && !isDecendant(target, import_box) && !isDecendant(target, import_link))
				lsclient.HideImportBox();
				
			if (print_options.style.display == 'block' && !isDecendant(target, print_options) && !isDecendant(target, print_options_link))
				HidePrintOptions();
				
			if (!isDecendant(target, outliner) && !isDecendant(target, toolbar) && !isDecendant(target, edit_box))		//  && !(upload_file_input != null && target == upload_file_input)
				lsclient.DeselectRow();
		}
		else alert("Upload in progress. Please wait.");
	}
	catch(err)
	{
//		alert('some error');
	}
}

var gElementInFocus = null;
TrackElementFocus=function(e)
{ 
	gElementInFocus = e;
    alert(gElementInFocus+" gets focus");
}

TrackElementBlur=function(e)
{
	if (gElementInFocus == e)
	{
		gElementInFocus = null;
		alert(e + " lost focus");
	}
	else alert('no element in focus');
}

// this function is used when we are handling click outside a particular div
function isDecendant(decendant, ancestor)
{
	return ((decendant.parentNode==ancestor) || (decendant.parentNode!=document) &&	isDecendant(decendant.parentNode,ancestor));
}

function ShowAlertReadOnly()
{
	alert("Sorry, you are currently in read only mode.\nYou need to enter Edit mode or wait till others have released their lock.");
}

function HandleSelectedDate(selected_date)
{
	lsclient.DidSelectDueDate(selected_date);
}

function ShowColumn(col)
{
	var outliner_div = document.getElementById('outliner');
	switch (col)
	{
	case 'attachment':	AddClass(outliner_div, 'hasattachments');
						break;
						
	case 'assigned-to': AddClass(outliner_div, 'hasassigned-to');
						break;
						
	case 'duedate': 	AddClass(outliner_div, 'hasduedate');
						break;
						
	case 'amount': 		AddClass(outliner_div, 'hasamount');
						break;
	}
}

function ScrollToRow(row_id)
{
//	$jq.scrollTo($jq(row_id), 800);
}

// PRINTING OPTIONS
function ShowPrintOptions()
{
//alert(document.getElementById('print-options').style.display);
	document.getElementById('print-options').style.display = 'block';
//alert(document.getElementById('print-options').style.display);
}

function HidePrintOptions()
{
	document.getElementById('print-options').style.display = 'none';
}

var gBackground = true;
var gBorders = true;
var gHeaders = true;
function ToggleBackgrounds()
{

	if (gBackground)
	{
		document.getElementById('backgrounds').style.display = 'none';
		document.getElementById('blank').style.display = 'block';
	}
	else
	{
		document.getElementById('backgrounds').style.display = 'block';
		document.getElementById('blank').style.display = 'none';
	}
	gBackground = !gBackground;
}

function ToggleBorders()
{
	if (gBorders)
		document.getElementById('borders').style.display = 'none';
	else document.getElementById('borders').style.display = 'block';

	gBorders = !gBorders;
}

function ToggleHeaders()
{
	if (gHeaders)
		document.getElementById('headers').style.display = 'none';
	else document.getElementById('headers').style.display = 'block';

	gHeaders = !gHeaders;
}

function ToggleBullets(style)
{
	if (style == 'bullet')
	{
		document.getElementById('numbers').style.display = 'none';
		document.getElementById('bullets').style.display = 'block';
	}
	else
	{
		document.getElementById('numbers').style.display = 'block';
		document.getElementById('bullets').style.display = 'none';
	}
}