﻿/*TDL Utils 1.5
  Author: Marcin Szpak, bestmetronome.com, reAKCJA.org, Samotnosc.org, Spont.pl, Sponter.pl
  copyrights (C) 2009-2010, 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;
    if (innerHTML!="")
        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)) 
	{
        var cn=elem.className || "";
		elem.className=cn+" "+name;
		return false; //if already on classname
	}
	else
	{
        var cn=elem.className || "";
		elem.className=cn+" "+name;
		return true;
	}
}

//DOM CLASSNAME TOGGLE - adds/removes name string to/from className. 
function domClassNameToggle(elem,name)
{
	if (!domClassNameRemove(elem,name)) 
        domClassNameAdd(elem,name);
}


//DOCUMENT LOCATION - return document location - by default removes params (after &,?,#)
function documentLocation(leaveSlash,withParams)
{
    var dl=document.location+"";
    if (withParams) return dl;
    if (dl.indexOf("?")>=0) dl=dl.substring(0,dl.indexOf("?"));
    if (dl.indexOf("&")>=0) dl=dl.substring(0,dl.indexOf("&"));
    if (dl.indexOf("#")>=0) dl=dl.substring(0,dl.indexOf("#"));
    if (!leaveSlash)
        if (dl.charAt(dl.length-1)=="/") dl=dl.substring(0,dl.length-1);
    return dl;
}

//DOCUMENT LOCATION PARAMS - return url params {param_name:value,param_name2:value,...,"#":document_position}
function documentLocationParams()
{
    var params={};
    var dl=document.location+"";
    var dlh=dl.split("#");
    if (dlh.length>1) //cut # hash document position
    {
        dl=dlh[0];
        params["#"]=dlh[1];
    }    
    var dlp=dl.split(/[\&\?]/);
    for (var i=1;i<dlp.length;i++) //omit first elem - url address
    {
        var par=dlp[i];
        var para=par.split("=");
        if (para.length>1)
            params[para[0]]=para[1];
        else params[para[0]]="";
    }
    return params;
}

//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){}
	}
}

//ELEM SET OPACITY - sets opacity in range [0..100]
function elemSetOpacity(elem,op100)
{
	if (op100>100) op100=100;
	if (op100<0) op100=0;
	
	var op1 = op100/100;

	if (op100<1) op100=1; //IE7 bug

	if (op100==100) elem.style.filter=""; //IE hover bug
	else elem.style.filter="alpha(opacity="+op100+")";
	elem.style.opacity=op1;
}

function elemFadeStep(elemId, stepNum, steps, fromOpacity, delta, timePerStep)
{
    elemSetOpacity(docEl(elemId), Math.round(parseInt(fromOpacity) + (delta * stepNum)));

    if (stepNum < steps)
        setTimeout("elemFadeStep('" + elemId + "', " + (stepNum+1) + ", " + steps + ", " + fromOpacity + ", " + delta + ", " + timePerStep + ");", timePerStep);
}

//ELEM FADE - fades opacity from fromOpacity to toOpacity
function elemFade(elemId, fromOpacity, toOpacity, time, fps)
{
	var steps = Math.ceil(fps * (time / 1000));
	var delta = (toOpacity - fromOpacity) / steps;
	
	elemFadeStep(elemId, 0, steps, fromOpacity, delta, (time / steps));
}

function arrayJoin(array1,array2)
{
    var a3=new Array(array1.length+array2.length);
    var ai=0;
    for (var i=0;i<array1.length;i++) a3[ai++]=array1[i];
    for (var i=0;i<array2.length;i++) a3[ai++]=array2[i];
    return a3;
}

//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="";
var textSafePromptAllow=[false,false,false];
function textSafePrompt(msg,def,handler,allowNull,allowDefault,allowEmpty)
{
    if (typeof msg!='undefined') //init values
    {
        textSafePromptHandler=handler;
        textSafePromptAllowNull=allowNull;
        textSafePromptMessage=msg;
        textSafePromptDefault=def;
        textSafePromptAllow=[allowNull,allowDefault,allowEmpty];
    }
    var t0=new Date().getTime();
    var res=prompt(textSafePromptMessage,textSafePromptDefault);
    var t1=new Date().getTime();
    if (t1-t0<30 || (!textSafePromptAllow[0] && (typeof res=='undefined' || res==null)) || (!textSafePromptAllow[1] && res==textSafePromptDefault)  || (!textSafePromptAllow[1] && textTrim(res+"")==""))
        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)
{
    textNoEmptyAlertElem(docEl(fieldId),alertMsg,fieldDef)
}

function textNoEmptyAlertElem(elem,alertMsg,fieldDef)
{
	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();
var textSelectAllFirstElem=null;
function textSelectAllFirst(elem)
{
	if (typeof(textSelectAllFirstArr[elem.getAttribute("id")+""])=='undefined')
	{
		try{
            textSelectAllFirstElem=elem;
            if (!elem.getAttribute("id"))
                elem.select();
            else
                setTimeout("textSelectAllFirstElem.select();",200); //Chrome fix
			textSelectAllFirstArr[elem.getAttribute("id")+""]=true;
		}catch(e){};
	}
}

//SELECT ALL - selects input text (.select()) - usage: onfocus="selectAll(this);"
var textSelectAllElem=null;
function textSelectAll(elem)
{
    try{
        textSelectAllElem=elem;
        setTimeout("textSelectAllElem.select();",200); //Chrome fix
    }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 COMPARE - returns: -1 if date1<date2; 1 if date1>date2; 0 if equal
function dateCompare(date1,date2)
{
    var do1=dateOnly(date1);
    var do2=dateOnly(date2);
    if (do1<do2) return -1;
    if (do1>do2) return 1;
    return 0;
}

//TODO:use dateCompare
//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 Math.floor((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 TEST - test if browser supports cookies
function cookieTest()
{
	cookieSet("QKiTST","9283","",1);
	if (cookieGet("QKiTST")=="9283")
	{
		cookieSet("QKiTST","","",0);
		return true;
	}
	else return false;
}

//COOKIE SET
function cookieSet(name,value,domain,expiredays)
{
	cookieSetExp(name,value,domain,expiredays,0);
}

//COOKIE SET EXP - additional param expirehours
function cookieSetExp(name,value,domain,expiredays,expirehours)
{
	var exdate=new Date();
	exdate.setDate(exdate.getDate()+expiredays);
	exdate.setHours(exdate.getHours()+expirehours);
//	document.cookie=name+ "=" +escape(value)+";path=/"+((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
	document.cookie=name+ "=" +escape(value)+";path=/"+((expiredays==null) ? "" : ";expires="+exdate.toGMTString())+(domain?(";domain=."+domain):"");	
}

//COOKIE GET
function cookieGet(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 "";
}

//LANG BROWSER GET
//if len2 then leaves only 2 first characters 
function langBrowserGet(len2)
{
    var lang="";
    if (typeof window.navigator.language !='undefined') 
        lang=window.navigator.language.toUpperCase();
    else if (typeof window.navigator.userLanguage !='undefined')
        lang=window.navigator.userLanguage.toUpperCase();
    if (len2)
        lang=lang.substring(0,2);
    return lang;
}

var langCookieName="userLang";
//LANG REDIRECT
//    langPaths -    map with pairs "EN":"path","PL":"path",...,"DEF":"path"
//    autoHostPath - if true then adds prefix with http:// ... / (up to first slash "/")
function langRedirect(cookieHeader,langPaths,autoHostPath)
{
    var langBrowser=langBrowserGet(true);
    var langCookie=cookieGet(cookieHeader,langCookieName);
    var siteLangPath="";
    
    if (typeof langPaths[langCookie]!='undefined') siteLangPath=langPaths[langCookie];
    else if (typeof langPaths[langBrowser]!='undefined') siteLangPath=langPaths[langBrowser];
    else siteLangPath=langPaths["DEF"];
    
    var hostPath="";
    if (autoHostPath)
    {
        var dl=document.location+"";
        hostPath=dl.substr(0,8);//http[s]
        dl=dl.substr(8);
        hostPath+=dl.substr(0,dl.indexOf("/"));
    }
    var dln=hostPath+siteLangPath;
    if (document.location!=dln)
        document.location=dln;
}

//LANG SAVE - used when click on flag button
function langSave(cookieHeader,lang,cookieDomain)
{
    cookieDomain=cookieDomain || "";
    cookieSet(cookieHeader,langCookieName,lang,cookieDomain,30);
}

function htmlLoadXMLIE(url)
{
	var xmlDoc=null;
	try { xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); }
	catch(e) { return false; }
	
	xmlDoc.async=false;
	xmlDoc.load(url);
	return xmlDoc;
}

function htmlLoadXMLHTTP(url,xmlMode)
{
	if (xmlMode)
	{
		var result=htmlLoadXMLIE(url);
		if (result) return result;
	}
	var req = false;
    if(window.XMLHttpRequest && !(window.ActiveXObject)) {
    	try { req = new XMLHttpRequest(); }
        catch(e) { req=false; }
    // branch for IE/Windows ActiveX version
    } else if(window.ActiveXObject) {
       	try { req = new ActiveXObject("Msxml2.XMLHTTP"); } 
        catch(e) 
        {
            try { req = new ActiveXObject("Microsoft.XMLHTTP"); }
            catch(e) { req = false; }
		}
    }
	if(req) 
    {
		req.open("GET", url, false);
		req.send("");

		if (!xmlMode)
 			return req.responseText;
		else
 			return req.responseXML;
	}
	else return "";
};

//HTML LOAD - loads synchronously (wait for result) url - returns result or ""
function htmlLoad(url)
{
	return htmlLoadXMLHTTP(url,false);
}

//SCRIPT LOAD - asynchronously loads script - set refreshMilis to -1 to avoid caching 
//              default 2 minutes cache (browser cache)
function scriptLoad(url,refreshMilis)
{
    refreshMilis=refreshMilis || 1000*60*2; //refresh each 2 minutes
    var refrInt=Math.round((new Date().getTime())/refreshMilis);
  	var se=document.createElement("script");
    var hasQ=false;
    if (url.indexOf("?")>=0) hasQ=true;
    if (refreshMilis<=0) refrInt=Math.random();
    se.src=url+(hasQ?"&":"?")+"SLMRInt="+refrInt;
	document.body.appendChild(se);
}
