﻿/*TDL Utils 1.0
  Author: Marcin Szpak, bestmetronome.com, reAKCJA.org
  copyrights (C) 2009, All rights reserved */
 

//GET ELEMENTS BY NAME - IE6 fix
if(typeof(window.external) != 'undefined' && document.attachEvent) {
     document.getElementsByName = function(name, tag) {
           if(!tag) tag = '*';
           var elems=document.getElementsByTagName(tag),x=elems.length,i,res=[];
           for(i=0;i<x;i++){
                 att = elems[i].getAttribute('name');
                 if(att == name) res.push(elems[i]);
           }
           return res;
     }
}

//DOC EL
function docEl(id)
{
	return document.getElementById(id);
}

//DOM APPEND CHILD
function domAppendChild(elem,type,id,className,innerHTML)
{
    id=id || "";
    className=className || "";
    innerHTML=innerHTML || "";
    var el=document.createElement(type);
    if (id!="")
        el.setAttribute("id",id);
    if (className!="")
        el.className=className;
    el.innerHTML=innerHTML;
    elem.appendChild(el);
}

//DOM CREATE ELEMENT
function domCreateElement(type,id,className,innerHTML)
{
    id=id || "";
    className=className || "";
    innerHTML=innerHTML || "";
    var el=document.createElement(type);
    if (id!="")
        el.setAttribute("id",id);
    if (className!="")
        el.className=className;
    el.innerHTML=innerHTML;
    return el;
}

//DOM REMOVE ALL CHILDREN
function domRemoveAllChildren(elem)
{
	while (elem.childNodes.length>0) elem.removeChild(elem.lastChild);
}

//DOM CLASSNAME REMOVE - remove name string from className. Return true if name was removed. If not - return false;
function domClassNameRemove(elem,name)
{
	var cn=elem.className;	

	cn.replace(new RegExp(),name);
    var cn1=cn.replace(new RegExp("\\s+"+name+"\\s+","g"), " ");
    var cn2=cn.replace(new RegExp("^"+name+"\\s+","g"), "");
    var cn3=cn.replace(new RegExp("\\s+"+name+"$","g"), "");
    var cn4=cn.replace(new RegExp("^"+name+"$","g"), "");
		
	if (cn!=cn1) elem.className=cn1;
	else if (cn!=cn2) elem.className=cn2;
	else if (cn!=cn3) elem.className=cn3;
	else if (cn!=cn4) elem.className=cn4;
	else return false; //return false if no change
	
	return true;	
}

//DOM CLASSNAME ADD - add name string to className. Return true if name was added. otherwise return false
function domClassNameAdd(elem,name)
{
	if (domClassNameRemove(elem,name)) 
	{
		elem.className+=" "+name;
		return false; //if already on classname
	}
	else
	{
		elem.className+=" "+name;
		return true;
	}
}

//DOCUMENT GO TO LOCATION
function documentGoToLocation(name)
{
	var loc=document.location.toString();
	var hashI=loc.indexOf("#");
	if (hashI>0) loc=loc.substring(0,hashI);
	document.location=loc+"#"+name;
}

//ELEM CLICK
function elemClick(elem)
{
	if (elem.click) elem.click();
	else
	{ 		
		try{
			elem.onclick();
		}catch(e){}
	}
}

//NUMBER FORMAT PRECISION - clips number representation removing precision digits
//TODO: switch to Math.round()... - maybe problem with 99.9 precision maxLength=2
function numberFormatPrecision(num,maxLength,maxPrecision)
{
    maxPrecision=maxPrecision || 1000;
    
    var numStr=(1.0*num)+"";
    var iDot=numStr.indexOf(".");
    if (iDot>=0)
    {
        var pre=numStr.substr(0,iDot);
        var post=numStr.substr(iDot+1);
        //clip precision digits (maxPrecision)
        while (post.length>maxPrecision && post.length>0) post=post.substr(0,post.length-1);
        //clip precision digits (maxLength)
        while (pre.length+post.length>maxLength && post.length>0) post=post.substr(0,post.length-1);
            
        if (post.length==0) return pre;
        else return pre+"."+post;
    }
    else return numStr;
}

//TEXT SAFE PROMPT - IE7 fix - when prompt dialogs disabled
var textSafePromptHandler=null;
var textSafePromptAllowNull=true;
var textSafePromptMessage="";
var textSafePromptDefault="";
function textSafePrompt(msg,def,handler,allowNull)
{
    if (typeof msg!='undefined') //init values
    {
        textSafePromptHandler=handler;
        textSafePromptAllowNull=allowNull;
        textSafePromptMessage=msg;
        textSafePromptDefault=def;
    }
    var t0=new Date().getTime();
    var res=prompt(textSafePromptMessage,textSafePromptDefault);
    var t1=new Date().getTime();
    if (t1-t0<30 || (!allowNull && (typeof res=='undefined' || res==null)))
        setTimeout("textSafePrompt()",50);
    else
        textSafePromptHandler(res);
}

//TEXTAREA SET - IE6 fix
function textareaSet(elem,val)
{
	try{
		elem.value=val;
	}catch(e)
	{
		elem.innerHTML=val;
	}	
}
    
//TEXT NO EMPTY ALERT - shows alert window when empty (or default) field
function textNoEmptyAlert(fieldId,alertMsg,fieldDef)
{
	elem=docEl(fieldId);
	elem.value=textTrim(elem.value);
	if (elem.value=="" || (fieldDef && elem.value==fieldDef))
	{ 
		alert(alertMsg);
		elem.value="";
		elem.focus();
		return false;
	} 
	return true;
}

//TEXT TRIM - trims string
function textTrim(str, chars) {
	return textLTrim(textRTrim(str, chars), chars);
}
function textLTrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
function textRTrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

//TEXT NL TO BR
function textNLtoBR(text)
{	
	return text.replace(/\n/gm,"<br/>");
}
//TEXT ENCODE HTML - encodes html entities
function textEncodeHTML(s){
	var result = '';
	for (var i = 0; i < s.length; i++){
		var c = s.charAt(i);
		result += {'<':'&lt;', '>':'&gt;', '&':'&amp;', '"':'&quot;'}[c] || c;
		}
		return result;
}

//TEXT FIELD LIMIT - limits textarea/input field - usage: onchange="..." onkeyup="..."
function textFieldLimit(limitField, limitNum) {
	if (limitField.value.length > limitNum) {
		limitField.value = limitField.value.substring(0, limitNum);
	} 
}

//SELECT ALL FIRST - selects input text (.select()) - usage: onfocus="selectAllFirst(this);"
var textSelectAllFirstArr=new Array();
function textSelectAllFirst(elem)
{
	if (typeof(textSelectAllFirstArr[elem.getAttribute("id")+""])=='undefined')
	{
		try{
			elem.select();
			textSelectAllFirstArr[elem.getAttribute("id")+""]=true;
		}catch(e){};
	}
}

//TEXT ADD0 - adds trailing 0:  0,...,9 -> 00,...,09
function textAdd0(num)
{
	if (num>9) return num+"";
	else return "0"+num;	
}

//TEXT ADD TRAILING - adds trailing 0:  0,...,9 -> 00,...,09
function textAddTrailing(text,len,character)
{
	var addT="";
	if (text.length<len)
		for (var i=0;i<len-text.length;i++)
			addT+=character;
	return addT+text;
}


//TEXT ESCAPE AMP - change "&" into "&amp;"
function textEscapeAmp(text)
{
	return text.replace(new RegExp("\&", "g"), "%26");
}

//TEXT ESCAPE  - change "&#;+" into corresponding %XX
function textEscape(text)
{ // cant use JS escape because of ąęćś - unicode ...
	return text.replace(new RegExp("\&", "g"), "%26").replace(new RegExp("#", "g"), "%23").replace(new RegExp(";", "g"), "%3B").replace(new RegExp("\\+", "g"), "%2B");
}

//TEXT WORD LIMIT
function textWordsLimit(text,maxWordLen)
{
    maxWordLen= maxWordLen || 15;
    var words=text.split(" ");
    var textN="";
    for (var j=0;j<words.length;j++)
    {
        var w=words[j];
        var wN="";
        var parts=Math.ceil(w.length/maxWordLen);
        var partLen=Math.ceil(w.length/parts);
        for (var i=0;i<parts;i++)
        {
            if (i<parts-1)
                wN+=w.substring(i*partLen,(i+1)*partLen)+" ";
            else wN+=w.substring(i*partLen);
        }
        textN+=wN+((j==words.length-1)?"":" ");
    }    
    return textN;
}
//TEXT SERIALIZE OBJECT
//  serialize object -> joins object properties into string (with cipher or not)
//  objs - array of objects
//  sepObj - text separator between objects
//  sepProp - text separator between properties (and property values - prop, propValue, prop2, prop2Value, ...)
//TODO:  cipher - not implemented yet
function textSerializeObjects(objs,cipher,sepObj,sepProp)
{
    sepObj = sepObj || "TDLSepO";
    sepProp = sepProp || "TDLSepP";
        
    var osA=new Array();
    for (var o in objs)
    {
        var propA=new Array();
        for (var prop in objs[o]) 
        {
            propA[propA.length]=""+prop;
            propA[propA.length]=""+objs[o][prop];
        }
    
        osA[osA.length]=propA.join(sepProp); //join properties, save object
    }
    //TODO:cipher here
    return osA.join(sepObj);
}

//TEXT DESERIALIZE OBJECT
function textDeserializeObjects(text,cipher,sepObj,sepProp)
{
    sepObj = sepObj || "TDLSepO";
    sepProp = sepProp || "TDLSepP";

    if (text=="") return new Array();
    var textos=text.split(sepObj);

    var osA=new Array();
    for (var texto in textos)
    {   
        var textProps=textos[texto].split(sepProp);
        var o=new Array();
        for (var pi=0;pi<textProps.length;pi+=2) //property, propertyValue, property, propertyValue,...
        {
            o[textProps[pi]]=textProps[pi+1];
        }
        osA[osA.length]=o;
    }
    //TODO:decipher here
    return osA;
}

//TEXT CIPHER - symmetric cipher - xor like - codes/encodes letters/numbers/symbols
//var textCipherChars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ`1234567890-=][\\';/.,~!@#$%^&*()_+}{|\":?><";
//var textCipher
//function textCipher(text)
//{     
//}

//DATE MIX - mix date part and time part from two dates into new one
function dateMix(dateDate,timeDate)
{
	return new Date(dateDate.getFullYear(),dateDate.getMonth(),dateDate.getDate(),timeDate.getHours(),timeDate.getMinutes(),timeDate.getSeconds(),timeDate.getMilliseconds());	
}

//DATE ONLY - only date set - time part = 0
function dateOnly(date)
{
	return new Date(date.getFullYear(),date.getMonth(),date.getDate());
}
//DATE EQUAL - test date part equality
function dateEqual(date1,date2)
{
	if (date1.getDate()==date2.getDate() &&
		date1.getMonth()==date2.getMonth() &&
		date1.getFullYear()==date2.getFullYear()) return true;
	else return false;
}

//DATE ADD DAY - returns new date with days added
function dateAddDays(date,daysNum)
{
	return new Date(date.getTime()+daysNum*1000*60*60*24);
}

//DATE ADD MINUTES - returns new date with minutes added
function dateAddMinutes(date,minutesNum)
{
	return new Date(date.getTime()+minutesNum*1000*60);
}

//DATE DAY DIFF - returns difference in integer days: date1-date2
function dateDayDiff(date1,date2)
{
	var d1=dateOnly(date1);
	var d2=dateOnly(date2);
	return (d1.getTime()-d2.getTime())/1000/60/60/24;
}

//DATE GET DESCRIPTION - returns date description (today, tomorrow, yesterday, etc...) - or null if non descriptive day
function dateGetDescription(dateNow,date)
{
	var datesDesc={0:"dzisiaj",1:"jutro",2:"pojutrze",7:"za tydzień","-1":"wczoraj","-2":"przedwczoraj"};
	var datePastDesc="dawno temu";
	
	var diff=-dateDayDiff(dateNow,date);
	if (datesDesc[diff]) return datesDesc[diff];
	if (diff<0) //past
		return datePastDesc;
	return null;
}

//DATE DATE STRING LONG - locale date + day of week + day description (Today, tomorrow ...)
function dateDateStringLong(date,dateNow)
{
	var days=new Array("Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota");
	var desc=dateGetDescription(dateNow,date);
	if (desc==null) desc="";
	else desc=" - "+desc;
	return date.toLocaleDateString()+", "+days[date.getDay()]+desc; 		
}

//DATE DATE STRING
function dateDateString(date,year,sep)
{	
    sep=sep||"-";
	return (year?(date.getFullYear()+sep):"")+textAdd0(date.getMonth()+1)+sep+textAdd0(date.getDate());
}

//DATE TIME STRING
function dateTimeString(date,seconds)
{	
	return textAdd0(date.getHours())+":"+textAdd0(date.getMinutes())+(seconds?":"+textAdd0(date.getSeconds()):"");
}

//DATE UPDATE TIMESTAMPS
function dateUpdateTimestamps(elemsName,showDate,showTime,separator)
{
	separator = separator || " ";
	var timestamps=document.getElementsByName(elemsName);
	for (i=0;i<timestamps.length;i++)
	{
		var intVal=parseInt(timestamps[i].innerHTML,10);
		if (!isNaN(intVal))
		{
			var ts="";
			var tsDate=new Date(intVal*1000);
			if (showDate)
				ts=tsDate.toLocaleDateString();
			if (showDate && showTime) ts+=separator;			
			if (showTime)
				ts+=dateTimeString(tsDate,true);
				
			timestamps[i].innerHTML=ts;
		}
	}
}


//COOKIE SET
function cookieSet(header, name,value,domain,expiredays)
{
	cookieSetExp(header,name,value,domain,expiredays,0);	
}

//COOKIE SET EXP - additional param expirehours
function cookieSetExp(header,name,value,domain,expiredays,expirehours)
{
	name=header+name;
	var exdate=new Date();
	exdate.setDate(exdate.getDate()+expiredays);
	exdate.setHours(exdate.getHours()+expirehours);
	document.cookie=name+ "=" +escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
	document.cookie=name+ "=" +escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString())+";domain=."+domain;	
}

//COOKIE GET
function cookieGet(header,name)
{
	name=header+name;
	if (document.cookie.length>0)
	{
		c_start=document.cookie.indexOf(name + "=");
		if (c_start!=-1)
		{
			c_start=c_start + name.length+1;
		    c_end=document.cookie.indexOf(";",c_start);
		    if (c_end==-1) c_end=document.cookie.length;
		    return unescape(document.cookie.substring(c_start,c_end));
	    }
	}
	return "";
}

