/*
 * Generic utilities
 */
Util = new function(){};

Util.getCookie = function(name)
{
	var a_all_cookies = document.cookie.split( ';' );
	var a_temp_cookie = '';
	var cookie_name = '';
	var cookie_value = '';
	var b_cookie_found = false; // set boolean t/f default f

	for ( i = 0; i < a_all_cookies.length; i++ )
	{
		a_temp_cookie = a_all_cookies[i].split( '=' );
		cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');

		if ( cookie_name == name )
		{
			b_cookie_found = true;
			if ( a_temp_cookie.length > 1 )
			{
				cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
			}
			return cookie_value;
			break;
		}
		a_temp_cookie = null;
		cookie_name = '';
	}
}

Util.setCookie = function(name, value)
{
	document.cookie = name + "=" + escape( value );
}

Util.trim = function (astr) 
{
	var stringa = astr + "";
	if (stringa.indexOf(" ")!=-1)
	{
		while (stringa.substring(0,1) == ' '){
	        stringa = stringa.substring(1, stringa.length);
	    }
	    while (stringa.substring(stringa.length-1, stringa.length) == ' '){
	        stringa = stringa.substring(0,stringa.length-1);
	    }
	}
    return stringa;
};

Util.swap = function(el1, el2)
{
	bEl = $(el2)[0];
	var aEl = $(el1)[0];

	try
	{
		var t = aEl.parentNode.insertBefore(document.createTextNode(''), aEl);
		try { bEl.parentNode.insertBefore(aEl, bEl) } catch (e) { console.log(e) }
		t.parentNode.insertBefore(bEl, t);
		t.parentNode.removeChild(t);
	}
	catch ( e )
	{
		console.log(e);
	}

	return this;
}

Util.checkPhoneNumber = function (astr) 
{
	var ph = Util.trim(astr+"");
	if (ph.length<9)
		return false;
	
	for (var i=0;i<ph.length;i++)
	{
		if ("0123456789".indexOf(ph.charAt(i))==-1)
			return false;
	}
	return true;
};

Util.object2queryString = function (obj) 
{
	if (!obj)
		return "";
	var s = [];
	for (var p in obj)
	{
		if (obj[p])
			s.push(p + "=" + escape(obj[p]));
	}
	return s.join("&");
}

Util.queryString2object = function (queryString) 
{
	var query = queryString;
	if (!query && window.location.search.indexOf("?")!=-1)
		query = document.location.search.substring(1);
	_queryparameters = {};
	if (query)
	{
		var pairs = new Array();
		if ( query.indexOf("&")==-1 )
			pairs[0] = query;
		else
			pairs = query.split("&");
	
	 	for (var i=0;i<pairs.length;i++)
	 	{
	 		var pos = pairs[i].indexOf('=');
	 		if (pos >= 0)
	 		{
	 			var pn = pairs[i].substring(0,pos);
	 			var pv = pairs[i].substring(pos+1);
	 			_queryparameters[pn]=unescape(pv);
	 		}
		}
	}
	return _queryparameters;
}

Util.string2uri = function(s)
{
	if (!s)
		return s;
	if (s==null)
		return s;
	if (s =="")
		return s;
	
	while (s.indexOf('\t')!=-1)
		s = s.replace('\t', ' ');
	while (s.indexOf("\r\n")!=-1)
		s = replace(s, "\r\n", " ");
	while (s.indexOf('\n')!=-1)
		s = s.replace('\n', ' ');
	while (s.indexOf('\r')!=-1)
		s = s.replace('\r', ' ');
	while (s.indexOf("  ")!=-1)
		s = replace(s, "  ", " ");
	s = Util.trim(s).toLowerCase();
	var sb = [];
	for ( var i = 0; i < s.length; i++ )
	{
		var c = s.charAt( i );
        var sc = s.charCodeAt(i);
		if ( "abcdefghijklmnopqrstuvwxyz_-".indexOf(c)!=-1 )
			sb.push( c );
		else if ( c == ' ' )
			sb.push( "-" );
		else if ( sc == 133 )
			sb.push( "a" );
		else if ( sc == 138 )
			sb.push( "e" );
		else if ( sc == 141 )
			sb.push( "i" );
		else if ( sc == 149 )
			sb.push( "o" );
		else if ( sc == 151 )
			sb.push( "u" );
	}
	s = sb.join("");
	while (s.indexOf("--")!=-1)
		s = s.split("--").join("-");
	return s;
}


/*
 * Filter and query on javascript lists
 */
KQL = new function() {};

KQL.Sort = function(arr, field, desc)
{
	l = arr.sort(function(a,b) {
		return desc ? a[field] < b[field] : a[field] > b[field];
	})
	return l;
}

KQL.Operator = new function() 
{
	this.EQUALS = "=";
	this.GREATER = ">";
	this.GREATEREQUALS = ">=";
	this.LESS = "<";
	this.LESSEQUALS = "<=";
	this.STARTSWITH = "startsWith";
	this.CONTAINS = "contains";
	this.ENDSWITH = "endsWith";
	this.ISNULL = "isNull";
};

KQL.BooleanToken = new function() 
{
	this.AND = "and";
	this.OR = "or";
};

KQL.Clause = function(propertyPath, operator, value, not)
{
	var undef;
	this.propertyPath = propertyPath;
	this.value = value;
	this.not = not;
	this.operator = operator;
	
	this.match = function(obj)
	{
		if (!obj)
			return false;
		if (obj==null)
			return;
		var retVal = false;
		var val;
		try 
		{
			var p = propertyPath.split(".");
			for (var i=0;i<p.length;i++)
				val = i==0 ? obj[p[i]] : val[p[i]]; 
		}
		catch (e)
		{};
		
		if (val==undef || val==null)
		{
			if (this.operator == KQL.Operator.ISNULL ||
					this.operator == KQL.Operator.LESS ||
					this.operator == KQL.Operator.LESSEQUALS)
				retVal = true;
		}
		else
		{	
			if (this.operator == KQL.Operator.EQUALS)
			{
				retVal = (Util.trim(val) == Util.trim(this.value));
				if (!retVal)
					retVal = (val == this.value);
			}
			if (this.operator == KQL.Operator.LESS)
				retVal = val < this.value;
			if (this.operator == KQL.Operator.LESSEQUALS)
				retVal = val <= this.value;
			if (this.operator == KQL.Operator.GREATER)
				retVal = val > this.value;
			if (this.operator == KQL.Operator.GREATEREQUALS)
				retVal = val >= this.value;
			if (this.operator == KQL.Operator.CONTAINS)
				retVal = val.indexOf(this.value)!=-1;
			if (this.operator == KQL.Operator.STARTSWITH)
				retVal = val.indexOf(this.value)==0;
			if (this.operator == KQL.Operator.ENDSWITH)
				retVal = val.indexOf(this.value) == (val.length - this.value.length);
		}
		
		if (this.not)
			retVal = !retVal;
		
		return retVal;
	}
	
	this.toString = function()
	{
		var s = [];
		if (this.not)
			s.push("not");
		if (this.propertyPath)
			s.push(this.propertyPath);
		if (this.operator)
			s.push(this.operator);
		if (this.value)
			s.push(this.value);
		return s.join(" ");
	}
}

KQL.Filter = function()
{
	var undef;
	var m_elements = [];
	var m_not = false;
	
	// offset + limit
	this.offset = 0;
	this.limit = 0;
	
	this.not = function() { m_not = true; return this; }
	this.equals = function(propertyPath, value) { return this.addClause(propertyPath, KQL.Operator.EQUALS, value); }
	this.greater = function(propertyPath, value) { return this.addClause(propertyPath, KQL.Operator.GREATER, value); }
	this.greaterEquals = function(propertyPath, value) { return this.addClause(propertyPath, KQL.Operator.GREATEREQUALS, value); }
	this.less = function(propertyPath, value) { return this.addClause(propertyPath, KQL.Operator.LESS, value); }
	this.lessEquals = function(propertyPath, value) { return this.addClause(propertyPath, KQL.Operator.LESSEQUALS, value); }
	this.startsWith = function(propertyPath, value) { return this.addClause(propertyPath, KQL.Operator.STARTSWITH, value); }
	this.contains = function(propertyPath, value) { return this.addClause(propertyPath, KQL.Operator.CONTAINS, value); }
	this.endsWith = function(propertyPath, value) { return this.addClause(propertyPath, KQL.Operator.ENDSWITH, value); }
	this.isNull = function(propertyPath, value) { return this.addClause(propertyPath, KQL.Operator.ISNULL, value); }
	this.union = function(query)
	{
		var els = query.getElements();
		for (var i=0;i<els.length;i++)
			m_elements.push(els[i]);
	}
	
	this.getElements = function(){return m_elements;}
	this.and = function() { return this.addBooleanToken(KQL.BooleanToken.AND); }
	this.or = function() { return this.addBooleanToken(KQL.BooleanToken.OR); }
	
	this.addClause = function(propertyPath, operator, value)
	{
		if (m_elements.length==0 ||
				(m_elements.length>0 &&
				(m_elements[m_elements.length-1]==KQL.BooleanToken.AND ||
				m_elements[m_elements.length-1]==KQL.BooleanToken.OR)) )
		{
			m_elements.push(new KQL.Clause(propertyPath, operator, value, m_not));
			m_not = false;
		}
		return this;
	}
	
	this.addBooleanToken = function(token)
	{
		if (m_elements.length>0 &&
				m_elements[m_elements.length-1]!=KQL.BooleanToken.AND &&
				m_elements[m_elements.length-1]!=KQL.BooleanToken.OR)
		{
			m_elements.push(token);
			m_not = false;
		}
		return this;
	}
	
	this.toString = function()
	{
		return m_elements.join(" ");
	}
	
	this.offset = function(n)
	{
		this.offset = n ;
		return this ;
	}
	
	this.limit = function(n)
	{
		this.limit = n ;
		return this ;
	}
	
	this.match = function(obj)
	{
		var lastBoolean;
		if (m_elements.length==0)
			return true;
		var retVal = false;
		for (var i=0;i<m_elements.length;i++)
		{
			if (m_elements[i] == KQL.BooleanToken.AND ||
					m_elements[i] == KQL.BooleanToken.OR)
				lastBoolean = m_elements[i];
			else
			{
				var match = m_elements[i].match(obj);
				if (lastBoolean)
				{
					if (lastBoolean == KQL.BooleanToken.AND)
						retVal = match && retVal;
					else
						retVal = match || retVal;
				}
				else
					retVal = match;
			}
		}
		return retVal;
	}
	
	this.filter = function(list)
	{
		var nl = [];
		var offset = this.offset ;
		var limit = ( this.limit ? this.limit : list.length ) ;
		for (var i = offset ; i < offset+limit ; i++ )
		{	
			if (this.match(list[i]))
				nl.push(list[i]);
		}
		return nl;
	}
	
	this.count = function(list)
	{
		var c = 0;
		for (var i=0;i<list.length;i++)
		{	
			if (this.match(list[i]))
				c++;
		}
		return c;
	}
}
