﻿/*TDL Utils 1.5
  Author: Marcin Szpak, bestmetronome.com, reAKCJA.org, Samotnosc.org, Spont.pl, Sponter.pl, besttimestable.com, bestdrumtrainer.com
  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,title)
{
    id=id || "";
    className=className || "";
    innerHTML=innerHTML || "";
    title=title || "";
    var el=document.createElement(type);
    if (id!="")
        el.setAttribute("id",id);
    if (className!="")
        el.className=className;
    if (innerHTML!="")
        el.innerHTML=innerHTML;
    if (title!="")
        el.setAttribute("title",title);
    elem.appendChild(el);
}

//DOM CREATE ELEMENT
function domCreateElement(type,id,className,innerHTML,title)
{
    id=id || "";
    className=className || "";
    innerHTML=innerHTML || "";
    title=title || "";
    var el=document.createElement(type);
    if (id!="")
        el.setAttribute("id",id);
    if (className!="")
        el.className=className;
    if (innerHTML!="")
        el.innerHTML=innerHTML;
    if (title!="")
        el.setAttribute("title",title);
    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;
//return null if not found (not removed), otherwise
//return newClassName (after remove)
function domClassNameRemoveTest(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"), "");
		
    var ncn=null;
    
	if (cn!=cn1) ncn=cn1;
	else if (cn!=cn2) ncn=cn2;
	else if (cn!=cn3) ncn=cn3;
	else if (cn!=cn4) ncn=cn4;

    return ncn;
}
function domClassNameRemove(elem,name)
{
    var ncn=domClassNameRemoveTest(elem,name);
    if (ncn==null) return false; //return false if no change
    else
    {
        elem.className=ncn;
        return true;
    }
//	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 (domClassNameRemoveTest(elem,name)!=null) return false; //if already on classname
	else
	{
		elem.className=elem.className+" "+name;
		return true;
	}
}

//DOM CLASSNAME TOGGLE - adds/removes name string to/from className. 
function domClassNameToggle(elem,name)
{
	if (!domClassNameRemove(elem,name)) 
        return domClassNameAdd(elem,name);
    else return false;
}

//DOM CLASSNAME SWITCH - adds/removes name string to/from className depending on setOn parameter
function domClassNameSwitch(elem,name,setOn)
{
    if (setOn)
        return domClassNameAdd(elem,name);
    else
        return domClassNameRemove(elem,name);
}

//DOM CLASSNAME TEST - test if classname is set
function domClassNameTest(elem,name)
{
	return domClassNameRemoveTest(elem,name)!=null;
}

//DOM CLASSNAME ADD TREE - add name string to className of elem and all its descents
// TODO:test // if stopAtName is set than tree is cut if node has stopAtName in className
function domClassNameAddTree(elem,name)//,stopAtName)
{
    try{//try catch for IE child (probably text is a child)
//        if (stopAtName && domClassNameTest(elem,stopAtName)) return;
        domClassNameAdd(elem,name);
        for (var ei=0;ei<elem.childNodes.length;ei++)
            domClassNameAddTree(elem.childNodes[ei],name);
    }catch(e){};
}


//DOM GET FIRST ROOT - returns first ancestor with class=className or null if not exists
function domGetFirstRoot(elem,className)
{
	if (domClassNameTest(elem,className)) return elem;
	while (elem!=elem.parentNode && elem.parentNode) 
	{
		elem=elem.parentNode;
		if (domClassNameTest(elem,className)) return elem;
	}
	return null;
}
//DOM GET FIRST CHILD - returns child with class=className or null if not exists
function domGetFirstChild(elem,className)
{
    for (var c in elem.childNodes)
        if (domClassNameTest(elem.childNodes[c],className)) return elem.childNodes[c];
	return null;
}
//DOM GET ALL CHILDREN - returns children with class=className or null if not exists
function domGetAllChildren(elem,className)
{
    var ch=[];
    for (var c in elem.childNodes)
        if (domClassNameTest(elem.childNodes[c],className)) 
            ch.push(elem.childNodes[c]);
    if (ch.length>0) return ch;
	else return null;
}

//DOCUMENT LOCATION - return document location - by default removes params (after &,?,#)
function documentLocation(leaveSlash,withParams,withoutHash)
{
    var dl=document.location+"";
    if (withoutHash) 
        if (dl.indexOf("#")>=0) dl=dl.substring(0,dl.indexOf("#"));
    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 MAKE LOCATION
function documentMakeLocation(name)
{
	var loc=document.location.toString();
	var hashI=loc.indexOf("#");
	if (hashI>0) loc=loc.substring(0,hashI);
    var newLoc=loc+"#"+name;	
    return newLoc;
}

//DOCUMENT GO TO LOCATION
function documentGoToLocation(name)
{
	document.location=documentMakeLocation(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;
}

var elemFadeStepTO=new Array();
function elemFadeStep(elemId, stepNum, steps, fromOpacity, delta, timePerStep)
{
    elemSetOpacity(docEl(elemId), Math.round(parseInt(fromOpacity) + (delta * stepNum)));

    if (stepNum < steps)
        elemFadeStepTO[elemId]=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));
}
//ELEM FADE STOP - stops fading of element
function elemFadeStop(elemId)
{
    if (elemFadeStepTO[elemId])
    {
        clearTimeout(elemFadeStepTO[elemId]);
        elemFadeStepTO[elemId]=null;
    }
}    
//ARRAY JOIN
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;
}

//COLOR GET HEX
function colorGetHexString(red,green,blue)
{
    return red.toString(16)+green.toString(16)+blue.toString(16);
}


//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||false,allowDefault||false,allowEmpty||false];
    }
    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] && textTrim(res+"")==textSafePromptDefault && textSafePromptDefault!="")  || (!textSafePromptAllow[2] && 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;
	}	
}

//TEXTAREA AUTO RESIZE - resizes height (rows) of textarea to view whole user's input string
// font100pxRatio - you have to calculate that. write some text "for example this one" (20 chars)
//                  calculate number of characters and measure the length in photoshop (e.g. 175pixels)
//                  font100pxRatio=20/1.75 in this case
// allowDecrease - if set than increases/decreases rows dynamicaly otherwise only increases
var textareaAutoResizeTmp=new Array();
// !#!#!#!#!#!# !#!#!#!#!#!# !#!#!#!#!#!# Alert: switches argumets - fontRatio at the end 
// !#!#!#!#!#!# !#!#!#!#!#!# !#!#!#!#!#!# !#!#!#!#!#!# !#!#!#!#!#!# !#!#!#!#!#!#
//TODO: calculate ratio!
function textareaAutoResize(ta,minRows,allowDecrease,font100pxRatio)
{
    font100pxRatio=font100pxRatio||11;
    var charNum=ta.offsetWidth/100.0*font100pxRatio;
    var rowsMem=0;
    if (typeof textareaAutoResizeTmp[ta]!='undefined') rowsMem=textareaAutoResizeTmp[ta];
    var rowsNum=ta.value.length/charNum;
    if (rowsNum>0.9)rowsNum+=0.3; //add 0.3 if not first line
    rowsNum=Math.ceil(rowsNum);
    var nl=(ta.value+"").match(new RegExp("\n","g"));
    var nlRows=0;
    if (nl) nlRows=nl.length;
        
    rowsNum+=nlRows;
    rowsNum=Math.max(rowsNum,minRows);
    if (!allowDecrease) rowsNum=Math.max(rowsNum,rowsMem);
    textareaAutoResizeTmp[ta]=rowsNum;
    ta.setAttribute("rows",rowsNum);
    return rowsNum;
}
    
//TEXT NO EMPTY ALERT - shows alert window when empty (or default) field
function textNoEmptyAlert(fieldId,alertMsg,fieldDef,noAlert)
{
    return textNoEmptyAlertElem(docEl(fieldId),alertMsg,fieldDef,noAlert);
}

function textNoEmptyAlertElem(elem,alertMsg,fieldDef,noAlert)
{
	elem.value=textTrim(elem.value);
	if (elem.value=="" || (fieldDef && elem.value==fieldDef))
	{ 
        if (!noAlert)
            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)
{
//TODO:test it vvv
    if (!elem.getAttribute("id")) elem.setAttribute("id",Math.random()+"X"+Math.random());
	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)
//{     
//}

//TEXT MAKE ANCHORS (e.g. baseIn = "akcjaspontan.pl", baseOut="http://akcjaspontan.pl, target="_blank", minLen=5 (full length without "http://"))
//  if minLen==-1 than we take whole baseIn string
function textMakeAnchors(text,baseIn,baseOut,className,minLen,target,noTrailingSlashes)
{
    var tmpValue="98098w45dgiuha348hgs";
    var tmpValue2in="23gdfvsj893h4bhklasdfb";
    var tmpValue2out="vznsaildf390bgfkndaw3r";
    if (minLen<=0)
        text=text.replace(new RegExp(baseIn+"([^\\s]*)","gmi"),"<a href='"+baseOut+"$1' class='"+className+"' target='"+target+"'>"+tmpValue2in+baseIn+"$1"+tmpValue2out+"</a>");
    else 
        text=  text.replace(new RegExp(baseIn+"([^\\s]{0,"+(minLen-1)+"}$)","gmi"),tmpValue+"$1")
                   .replace(new RegExp(baseIn+"([^\\s]{0,"+(minLen-1)+"}\\s)","gmi"),tmpValue+"$1")
//if >=minLen - link without baseIn prefix
                   .replace(new RegExp(baseIn+"([^\\s]*)","gmi"),"<a href='"+baseOut+"$1' class='"+className+"' target='"+target+"'>"+tmpValue2in+"$1"+tmpValue2out+"</a>")
//if <minLen - link with baseIn
                   .replace(new RegExp(tmpValue+"([^\\s]*)","gmi"),"<a href='"+baseOut+"$1' class='"+className+"' target='"+target+"'>"+tmpValue2in+baseIn+"$1"+tmpValue2out+"</a>");
                 
    if (typeof noTrailingSlashes!="undefined" && noTrailingSlashes)
        return text.replace(new RegExp(tmpValue2in+"/?","gmi"),"")
                   .replace(new RegExp("/?"+tmpValue2out,"gmi"),"");
    else
        return text.replace(new RegExp(tmpValue2in,"gmi"),"").replace(new RegExp(tmpValue2out,"gmi"),"");
}

//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;
		}
	}
}

//DATE PARSE TIME 
//parses time from string in form "HourCharMinute", Char - any char, Hour - HH or H, Minute - MM or M
//                     or in form "HourMinute", Hour - HH, Minute - M or M
//returns array Date 01-01-2000 HH:MM on success
//           or null if failed
function dateParseTime(textStr)
{
	var timeStr=textTrim(textStr);
	
	var regs=new Array(/^(\d\d?)\:(\d\d?)$/,
					   /^(\d\d?)\d?[^\d](\d\d?)\d?$/,
					   /^(\d\d)(\d\d?)\d?$/);	
	    
	for (var r=0;r<regs.length;r++)
	{	                   
		var rArr=timeStr.match(regs[r]);
		if (rArr) 
		{
            var r1=textLTrim(rArr[1],"0") || "0"; //remove trailing "0" - to avoid interpretation as octal numbers
            var r2=textLTrim(rArr[2],"0") || "0"; //remove trailing "0" - to avoid interpretation as octal numbers
			var hourPart=parseInt(r1)%24; 
			var minutePart=parseInt(r2)%60;
			if (!isNaN(hourPart) && !isNaN(minutePart)) //correct time
                return new Date(2000,0,1,hourPart,minutePart);
			else
                return null;
		}				
	}
    return null;
}

//TIMER STRING
//   returns timer string in format hh:mm:ss,mss
//   minFields - minimum number of fields from (hours, minutes, seconds, miliseconds)
//   maxFields - maximum number of fields 
function timerString(timestampMS,minFields,maxFields)
{	
    var fields=[Math.floor(timestampMS/(1000*60*60)),Math.floor((timestampMS/(1000*60))%60),Math.floor((timestampMS/1000)%60),Math.floor(timestampMS%1000)];
    var fieldsNum=fields.length;
    minFields=Math.min(Math.max(minFields,1),fieldsNum);
    maxFields=Math.min(Math.max(minFields,maxFields),fieldsNum);
   
    var separators=[":",":",","];
    var lengths=[2,2,2,3];
    
    var startField=0;
    for (var i=0;i<fields.length;i++) if (fields[i]==0) startField=i+1; else break;
    var endField=startField+maxFields-1;
    if (endField>fieldsNum-1) endField=fieldsNum-1;
    if (startField>endField-minFields+1) startField=endField-minFields+1;
    
    var tString="";
    
    for (var j=startField;j<=endField;j++)
        tString+=textAddTrailing(fields[j]+"",lengths[j],"0")+(j!=endField?separators[j]:"");
    
    return tString;
}

//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)
	{
        var c_start=-1;
        var dc=document.cookie+"";
        var matchPos=0;
        var cName=name + "=";
        do{
            c_start=dc.substring(matchPos).indexOf(cName);
            if (c_start==-1 || (c_start==0 && matchPos==0)) break; //not found or found at 0 index;
            if (dc.substring(matchPos+c_start-1,matchPos+c_start).search(new RegExp("[\;\,\\s\/]","g"))!=-1) //test previous char
            {
                c_start+=matchPos;
                break; //found at c_start index and previous char was correct
            }
            matchPos+=c_start+1;
        }while(true);
        
		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(langPaths,autoHostPath)
{
    var langBrowser=langBrowserGet(true);
    var langCookie=cookieGet(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 (documentLocation(true,true,true)!=dln)
    {
        langRedirectLocation=dln;        
        setTimeout("langRedirectHandler()",1000);
    }
}
var langRedirectLocation=null;
function langRedirectHandler()
{
    if (langRedirectLocation!=null)
        document.location=langRedirectLocation; 
}


//LANG SAVE - used when click on flag button
function langSave(lang,cookieDomain)
{
    cookieDomain=cookieDomain || "";
    cookieSet(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);
}




//DOCUMENT TITLE ANIM - animates title of the browser with text scroll: Winking Face+Sign+Body
function documentTitleAnim(sign,body)
{
    documentTitleVars["frame"]=0;
    documentTitleVars["bkp"]=document.title;
    documentTitleVars["titleSign"]=sign.substring(0,6)+": ";
    documentTitleVars["titleBody"]=body;
    documentTitleAnimFrame();
}

//bkp,titleSign,titleFace,titleBody,frame,maxFrames
var documentTitleVars={};
documentTitleVars["titleFace"]=["(O_O)","(O_O)","(O_O)","(O_O)","(O_O)","(O_O)","(O_O)","(O_O)","(O_O)","(O_O)","(O_O)","(O_O)","(O_O)","(O_O)","(~_O)","(~_O)","(O_O)","(O_O)","(O_O)","(O_O)","(~_~)","(~_~)","(~_~)"];
documentTitleVars["maxFrames"]=100;

function documentTitleAnimFrame()
{
    documentTitleVars["frame"]++;
    var frame=documentTitleVars["frame"];
    var sign=documentTitleVars["titleSign"];
    var face=documentTitleVars["titleFace"];
    var title="";
    var f2=0;
    var signBody=sign+documentTitleVars["titleBody"];
    //loop the title
    while (signBody.length<documentTitleVars["maxFrames"]) signBody+=" "+signBody;
    
    if (frame<=sign.length-1)
        title=sign.substring(0,frame);
    else if (frame<=sign.length+5)
        title=(face[0]+" ").substring(0,frame-sign.length)+" "+sign;
    else //if (frame>sign.length+5)
    {
        title=face[(frame-sign.length-5)%(face.length)]+" ";
        f2=(frame-5);
        var f3=f2%(signBody.length+11);
        title+=signBody.substring(f3-11,f3);
    }

    document.title=title;
    if (frame<documentTitleVars["maxFrames"] && f2<signBody.length+11)
        setTimeout("documentTitleAnimFrame()",200);
    else document.title=documentTitleVars["bkp"];
        
}

//USER LAST VISIT - returns user last visit (timestamp in sec) on page (domain) 
var userLastVisitSec=null;
function userLastVisit()
{
    if (userLastVisitSec==null) 
    {
        var TSSession=cookieGet("TDLULVessionTS");
        var TSLast=cookieGet("TDLULVLastTS");

        if (TSLast)
        {
            if (!TSSession) TSSession=TSLast;
            userLastVisitSec=TSSession*1;
            cookieSetExp("TDLULVessionTS",TSSession,"",0,1); //1 hour session - refreshed on every page refresh
        }
        else userLastVisitSec=0;
        cookieSet("TDLULVLastTS",Math.floor(new Date().getTime()/1000),"",30); //last = current time
    }
    return userLastVisitSec;
}

