/*
timeline.js
DOMElement.js
functions.ja
*/

Number.max = function (a,b)
{
    return (a<b ? b : a);
}

Number.min = function (a,b)
{
    return (a>b ? b : a);
}

Number.prototype.indexOf = function(i)
{
	return this.toString().indexOf(i);
}

Date.prototype.setDateTime = function(datetime)
{
    datetime = datetime.toString();
    this.setFullYear(datetime.substr(0,4),intVal(datetime.substr(5,2))-1,intVal(datetime.substr(8,2)));
}

Date.prototype.addDays = function(daynum,inclweekend)
{
    if( isUndefined(inclweekend) )
        inclweekend = true;
    var msec = this.getTime();
    var added = 1;
    while( added <= daynum )
    {
        this.setTime( msec + added * 24 * 60 * 60 * 1000);
        if( !inclweekend && (this.getDay() == 0 || this.getDay() == 6) )
            daynum++;
        added++;
    }
    
}

String.prototype._replace = function(what, to)
{
	return this.split(what).join(to);
}

String.prototype.endsWith = function(str)
{
    return (this.length-str.length)==this.lastIndexOf(str);
}

String.prototype.reverse = function() {
    var s = "";
    var i = this.length;
    while (i>0)
	{
        s += this.substring(i-1,i);
        i--;
    }
    return s;
}

String.prototype.trim = function()
{
    return(this.replace(/^\s+/,'').replace(/\s+$/,''));
}

String.prototype.toInt = function()
{
    var a = new Array();
    for (var i = 0; i < this.length; i++) {
        a[i] = this.charCodeAt(i);
    }
    return a;
}

String.prototype.url_encode = function() 
{
    var string = this.substring(0,this.length);
    string=escape(string);
    string=string.replace(new RegExp('\\+','g'),'%2B');
    return string.replace(new RegExp('%20','g'),'+');
};

String.prototype.url_decode = function() 
{
    var string = this.substring(0,this.length);
    string=string.replace(new RegExp('\\+','g'),' ');
    return unescape(string);
};

String.prototype.lpad = function(pad_length,pad_string) 
{
    var string = this.substring(0,this.length);
    while( string.length < pad_length )
        string = pad_string + string;
    return string;        
};

/**
*
*  MD5 (Message-Digest Algorithm)
*  http://www.webtoolkit.info/
*
**/

String.prototype.md5 = function() 
{
    var string = this.substring(0,this.length);
    
    function RotateLeft(lValue, iShiftBits) {
        return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
    }

    function AddUnsigned(lX,lY) {
        var lX4,lY4,lX8,lY8,lResult;
        lX8 = (lX & 0x80000000);
        lY8 = (lY & 0x80000000);
        lX4 = (lX & 0x40000000);
        lY4 = (lY & 0x40000000);
        lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
        if (lX4 & lY4) {
            return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
        }
        if (lX4 | lY4) {
            if (lResult & 0x40000000) {
                return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
            } else {
                return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
            }
        } else {
            return (lResult ^ lX8 ^ lY8);
        }
     }

     function F(x,y,z) { return (x & y) | ((~x) & z); }
     function G(x,y,z) { return (x & z) | (y & (~z)); }
     function H(x,y,z) { return (x ^ y ^ z); }
    function I(x,y,z) { return (y ^ (x | (~z))); }

    function FF(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };

    function GG(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };

    function HH(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };

    function II(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };

    function ConvertToWordArray(string) {
        var lWordCount;
        var lMessageLength = string.length;
        var lNumberOfWords_temp1=lMessageLength + 8;
        var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
        var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
        var lWordArray=Array(lNumberOfWords-1);
        var lBytePosition = 0;
        var lByteCount = 0;
        while ( lByteCount < lMessageLength ) {
            lWordCount = (lByteCount-(lByteCount % 4))/4;
            lBytePosition = (lByteCount % 4)*8;
            lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
            lByteCount++;
        }
        lWordCount = (lByteCount-(lByteCount % 4))/4;
        lBytePosition = (lByteCount % 4)*8;
        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
        lWordArray[lNumberOfWords-2] = lMessageLength<<3;
        lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
        return lWordArray;
    };

    function WordToHex(lValue) {
        var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
        for (lCount = 0;lCount<=3;lCount++) {
            lByte = (lValue>>>(lCount*8)) & 255;
            WordToHexValue_temp = "0" + lByte.toString(16);
            WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
        }
        return WordToHexValue;
    };

    function Utf8Encode(string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    };

    var x=Array();
    var k,AA,BB,CC,DD,a,b,c,d;
    var S11=7, S12=12, S13=17, S14=22;
    var S21=5, S22=9 , S23=14, S24=20;
    var S31=4, S32=11, S33=16, S34=23;
    var S41=6, S42=10, S43=15, S44=21;

    string = Utf8Encode(string);

    x = ConvertToWordArray(string);

    a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;

    for (k=0;k<x.length;k+=16) {
        AA=a; BB=b; CC=c; DD=d;
        a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
        d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
        c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
        b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
        a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
        d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
        c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
        b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
        a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
        d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
        c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
        b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
        a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
        d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
        c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
        b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
        a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
        d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
        c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
        b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
        a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
        d=GG(d,a,b,c,x[k+10],S22,0x2441453);
        c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
        b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
        a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
        d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
        c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
        b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
        a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
        d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
        c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
        b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
        a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
        d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
        c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
        b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
        a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
        d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
        c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
        b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
        a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
        d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
        c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
        b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
        a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
        d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
        c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
        b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
        a=II(a,b,c,d,x[k+0], S41,0xF4292244);
        d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
        c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
        b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
        a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
        d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
        c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
        b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
        a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
        d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
        c=II(c,d,a,b,x[k+6], S43,0xA3014314);
        b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
        a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
        d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
        c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
        b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
        a=AddUnsigned(a,AA);
        b=AddUnsigned(b,BB);
        c=AddUnsigned(c,CC);
        d=AddUnsigned(d,DD);
    }

    var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);

    return temp.toLowerCase();
}

Array.prototype.intArrayToString = function() {
    var a = new String();
    for (var i = 0; i < this.length; i++)
	{
        if(typeof this[i] != "number")
		{
            throw new Error("Array must be all numbers");
        }
		else if (this[i] < 0)
		{
            throw new Error("Numbers must be 0 and up");
        }
        a += String.fromCharCode(this[i]);
    }
    return a;    
}

Array.prototype.compareArrays = function(arr) {
    if (this.length != arr.length) return false;
    for (var i = 0; i < arr.length; i++)
	{
        if (this[i].compareArrays)
		{
            if (!this[i].compareArrays(arr[i])) return false;
            else continue;
        }
        if (this[i] != arr[i]) return false;
    }
    return true;
}

Array.prototype.map = function(fnc) {
    var a = new Array(this.length);
    for (var i = 0; i < this.length; i++) {
        a[i] = fnc(this[i]);
    }
    return a;
}

Array.prototype.exists = function (x)
{
    for (var i = 0; i < this.length; i++)
	{
        if (this[i] == x) return true;
    }
    return false;
}

Array.prototype.indexOf = function(n)
{
    for(var k in this)
    {
        if(this[k] == n) return k;
    }
    return -1;
}

Array.prototype.filter = function(fnc, keyAssign) {
    var a = new Array();
    for (var i = 0; i < this.length; i++)
	{
        if (fnc(this[i]))
		{
            if(keyAssign)
            {
               a[i] = this[i]; 
            }
            else
            {
                a.push(this[i]);
            }
        }
    }
    return a;
}

Array.prototype.max = function()
{
    var max = 0;
    for(var i=0 ; i<this.length ; i++)
    {
        if(this[i] > max) max = this[i];
    }
    return max;
}

Array.prototype.maxKey = function()
{
    var max = 0;
    for(var k in this)
    {
        if(parseInt(k) > max) max = parseInt(k);        
    }
    return max;
}

Array.prototype.random = function()
{
    return this[Math.floor((Math.random()*this.length))];
}

Object.prototype.extend = function(source)
{
	for(var name in source)
		this[name] = source[name];
}

Object.prototype.merge = function(source)
{
	for(var name in source)
		if(!isFunction(source[name]))
			this[name] = source[name];
}

Array.prototype.merge = function(source)
{
	var ret = new Array();
	for(var k=0 ; k<this.length ; k++)
	    ret.push(this[k]);
	
	for(var k=0 ; k<source.length ; k++)
		ret.push(source[k]);
	
	return ret;
}

Object.prototype.existsKey = function(key)
{
	for(var k in this)
	{
		if(k == key) return true;
	}
	return false;
}

Object.prototype.inObject = function(v)
{
	for(var k in this)
	{
		if(this[k] == v) return true;
	}
	return false;
}

Object.prototype.getKeys = function()
{
	var ret = new Array();
	for(var i in this)
		ret.push(i);
	return ret;
}

Object.prototype.changeValueKey = function()
{
	var ret = new Object();
	for(var k in this)
	{
		if(!isFunction(this[k]))
			ret[this[k]] = k;
	}
	return ret;
}

Object.prototype.orderByKey = function()
{
	var keys 	= this.getKeys().sort();
	var ret		= new Object();
	for(var i=0 ; i<keys.length ; i++)
	{
		ret[keys[i]] = this[keys[i]];
	}
	return ret;
}

Object.prototype.serialize = function(type)
{
	type = type.toUpperCase();
	if(type == 'JSON')
		return Serializer.JSON(this);
	else if(type == 'URL')
		return Serializer.URL(this);
	
	return this.toString();
}

document.getElementsByFilter = function(filter)
{
	return getElementsByFilter(document, filter);
}

DOMElement.extend('extend', function(source)
{
	for(var name in source)
		this[name] = source[name];
});

DOMElement.extend('setStyle', function(style)
{
	setStyle(this, style);
});

DOMElement.extend('addClassName', function(name)
{
	if(this.className.indexOf(name) == -1)
	{
		this.className+=' '+name;
	}
});

DOMElement.extend('delClassName', function(name)
{
	if(this.className.indexOf(name) != -1)
	{
		this.className = this.className.replace(name, '');
	}
});

DOMElement.extend('hasClassName', function(name)
{
    return (this.className.indexOf(name) != -1);
});

DOMElement.extend('getByTagNameList', function(list)
{
	var ret = new Array();
	for(var i in list)
	{
		if(isString(list[i]))
		{
			var el = this.getElementsByTagName(list[i]);
			for(var k=0 ; k<el.length ; k++)
			{
				DOMElement.proto(el.item(k));
				ret.push(el.item(k));				
			}
		}
	}
	return ret;
});

DOMElement.extend('getByTagName', function(tag)
{
	var e = this.getElementsByTagName(tag);
	for(var i=0 ; i<e.length ; i++)
	{
		DOMElement.proto(e.item(i));
	}
	return e;
});

DOMElement.extend('getElementsByClassName', function(className, tag, returnFirst, noProto)
{
	return getElementsByClassName(className, tag, this, returnFirst, noProto);
});

DOMElement.extend('copyTo', function(elm)
{
	return copyElement(this, elm);
});

DOMElement.extend('del', function()
{
	if(isElement(this.parentNode))this.parentNode.removeChild(this);
});

DOMElement.extend('getElementsByFilter', function(filter)
{
	return getElementsByFilter(this, filter);
});

DOMElement.extend('getParentBy', function(what, value)
{
	return getParentBy(this, what, value);
});

DOMElement.extend('moveBy', function(x, y, fps, frame)
{
	if(isUndefined(this._timeLine))
		this._timeLine = new TimeLine(25, 25);
	
	if(fps) 	this._timeLine.fps 		= fps;
	if(frame)	this._timeLine.frame 	= frame;
	
	this.startLeft 	= this.offsetLeft;
	this.startTop	= this.offsetTop;
	
	this._timeLine.addEvent(TIME_LINE_EVENT.ON_ENTER_FRAME, new CallBack(function(tl, p)
	{
		var step	= tl.frame;
		var curr	= tl.currentFrame;
		var left	= p.o.startLeft + (p.x / step * curr);
		var top		= p.o.startTop + (p.y / step * curr);
		p.o.style.left 	= left + 'px';
		p.o.style.top	= top + 'px';
	}, {x:x,y:y,o:this}));
	this._timeLine.play();
});

DOMElement.extend('fade', function(start, end, fps, frame)
{
	if(isUndefined(this._timeLine))
		this._timeLine = new TimeLine(25, 25);
	
	if(fps) 	this._timeLine.fps 		= fps;
	if(frame)	this._timeLine.frame 	= frame;
	this.style.filter = 'alpha(opacity='+start+')';
	this.style.opacity = start / 100;
	
	this._timeLine.addEvent(TIME_LINE_EVENT.ON_ENTER_FRAME, new CallBack(function(tl, p)
	{
		var step	= tl.frame;
		var curr	= tl.currentFrame;
		var d		= p.s > p.e ? -1 : 1;
		var offset	= p.s > p.e ? p.s-p.e : p.e-p.s;
		var alpha	= p.s + (offset / step * curr) * d;
		
		p.o.style.filter = 'alpha(opacity='+alpha+')';
		p.o.style.opacity = alpha / 100;
		
	}, {s:start,e:end,o:this}));
	this._timeLine.play();
});

DOMElement.extend('getCaretPosition', function()
{
	var iCaretPos = 0;

	if (document.selection)
	{
		/*this.focus ();
		var oSel = document.selection.createRange ();
		oSel.moveStart ('character', -this.value.length);
		iCaretPos = oSel.text.length;*/
		iCaretPos = 0;
	}
	else if (this.selectionStart || this.selectionStart == '0')
		iCaretPos = this.selectionStart;
	
	return (iCaretPos);
});

DOMElement.extend('setCaretPosition', function(iCaretPos)
{
	if (document.selection)
	{
		/*this.focus ();
		var oSel = document.selection.createRange ();
		oSel.moveStart ('character', -this.value.length);
		oSel.moveStart ('character', iCaretPos);
		oSel.moveEnd ('character', 0);
		oSel.select ();*/
	}
	else if (this.selectionStart || this.selectionStart == '0')
	{
		this.selectionStart = iCaretPos;
		this.selectionEnd = iCaretPos;
		this.focus ();
	}
});

DOMElement.extend('checkCharLength', function(charNumber)
{
	if(isUndefined(this.temp))
		this.temp = new Object();
	this.temp['scrollTop'] 	= this.scrollTop;
	this.temp['caret'] 		= this.getCaretPosition();
	
	if((this.value && this.value.length > charNumber) || (this.innerHTML && this.innerHTML.length > charNumber))
	{
		this.value = this.value.substring(0, charNumber);
		this.setCaretPosition(this.temp['caret']);
		this.scrollTop = this.temp['scrollTop'];
		return false;
	}
	return true;
});

DOMElement.extend('alpha', function(alpha)
{
	this.style.opacity = alpha / 100;
	this.style.filter = 'alpha(opacity='+alpha+')';
	return this;
});

DOMElement.extend('addAttribs', function(a)
{
	for(var k in a)
		if(!isFunction(a[k]))
		{
			this.setAttribute(k, a[k]);
			this[k] = a[k];
		}
	return this;
});

DOMElement.extend('getAttribs', function()
{
	var ret = new Array();
	for(var i=0 ; i<this.attributes.length ; i++)
	{
		ret.push({name:this.attributes[i].nodeName, value:this.attributes[i].nodeValue });
	}
	return ret;
});

DOMElement.extend('replaceAttrib', function(attribName,oldValue,newValue)
{
    if( this.getAttribute(attribName) == oldValue )
        this.setAttribute(attribName,newValue);
    
    /*for(var i=0, node ; node = this.childNodes.item(i) ; i++)
    {
        if(!isElement(node)) continue;
		
		DOMElement.proto(node);
        node.replaceAttrib(attribName,oldValue,newValue);        
    }*/
	
	var node = this.firstChild;
	while( node )
	{
		if(isElement(node))
		{		
			DOMElement.proto(node);
			node.replaceAttrib(attribName,oldValue,newValue);
		}
		
		node = node.nextSibling;
	}
});

DOMElement.extend('XPath', function(str, cache)
{
	return $X(str, cache, this);
});

//elementFromPoint
if (navigator.product == "Gecko")
{
	Document.prototype.elementFromPoint = function(x, y) {
		this.addEventListener("mousemove", this.elementFromPoint__handler, false);
		var event = this.createEvent("MouseEvents");
		var box = this.getBoxObjectFor(this.documentElement);
		var screenDelta = { x: box.screenX, y: box.screenY };
		event.initMouseEvent("mousemove", true, false, this.defaultView, 0,
		                      x + screenDelta.x, y + screenDelta.y, x, y,
		                      false, false, false, false, 0, null);
		this.dispatchEvent(event);
		this.removeEventListener("mousemove", this.elementFromPoint__handler, false);
		return this.elementFromPoint__target;
	}
	Document.prototype.elementFromPoint__handler = function (event) {
		this.elementFromPoint__target = event.explicitOriginalTarget;
	
		// reparent target if it is a text node to emulate IE's behavior
		if (this.elementFromPoint__target.nodeType == Node.TEXT_NODE)
			this.elementFromPoint__target = this.elementFromPoint__target.parentNode;
	
		// change an HTML target to a BODY target to emulate IE's behavior (if we are in an HTML document)
		if (this.elementFromPoint__target.nodeName.toUpperCase() == "HTML" && this.documentElement.nodeName.toUpperCase() == "HTML")
			this.elementFromPoint__target = this.getElementsByTagName("BODY").item(0);

		event.preventDefault();
		event.stopPropagation();
	}
	Document.prototype.elementFromPoint__target = null;
}


