Calendar = function()
{
    this.init();
};

var c = Calendar.prototype;
c.init = function()
{
    this.monthHeaderFormat = "%O %Y";

    this.style = 'single';

    var d = new Date();
    this.today = this._createDate(d.getFullYear(), d.getMonth(), d.getDate());
    this.currentdate = null;
    this.firstdate = null;
    this.lastdate = null;
    this.activemonth = null;
    this.expirieddate = null;

    this.divId = this._makeDivId();
    this._createSkeleton();

    this.scrollduration = 1;
    this.animation = 0;
    this.created = false;
};

c.setFirstDate = function(year, month, date)
{
    this.firstdate = new Object();
    this.firstdate.year = year;
    this.firstdate.month = month - 1;
    this.firstdate.date = date;
};

c.setLastDate = function(year, month, date)
{
    this.lastdate = new Object();
    this.lastdate.year = year;
    this.lastdate.month = month - 1;
    this.lastdate.date = date;
};

c.setToday = function(year, month, date)
{
    var d = new Date();
    this.today = new Object();
    this.today.year = (year == null? d.getFullYear() : year);
    this.today.month = (month == null ? d.getMonth() : month - 1);
    this.today.date = (date == null ? d.getDate(): date);
    this.activemonth = this._createDate(this.today.year, this.today.month);
};

c.setSelectedDate = function(year, month, date, focus)
{
    this.currentdate = this._createDate(year, month - 1, date);
    if(focus == true) this.activemonth = this._createDate(this.currentdate.year, this.currentdate.month);
}

c.setActiveMonth = function(year, month)
{
    this.activemonth = this._createDate(year, month);
};

c.setAnimation = function(index)
{
    if(index < 0 || index > 16)
    {
        alert("animation should be > 0 && < 16");
        return false;
    }
    this.animation = index;
};

c.close = function()
{
    this.obj.divObj.style.display = 'none';
};

c.setStyle = function(size)
{
    var btn = this._getElements('rightButton');
    if(size == 'double')
    {
        btn[0].style.left = 281;
        this.divObj.style.width = 299;
        this.style = 'double';
    }
    else if(size == 'single')
    {
        btn[0].style.left = 131;
        this.divObj.style.width = 150;
        this.style = 'single';
    }
};

c.show = function()
{
    document.getElementById(this.divId).style.display = 'block';
};

c.setInputs = function(io)
{
    for(var i in io) {
        var el = document.getElementById(io[i].id);
        if(el) {
            el.onfocus = this._show;
            el.io = io[i];
            el.calendar = this;
        }
    }
    this.io = io;
};

c.setDuration = function(t) {
    this.scrollduration = t;
};

c.setExpiried = function() {
    var a = arguments;
    if(a.length == 1) {
        if(a[0] == null || a[0] == 'current')
            date = this.today;
        else if(a[0] == 'firstDate')
            date = this.firstdate;
    }
    else if(a.length == 3) {
        date = this._createDate(a[0], a[1], a[2]);
    }
    else date = this.today;
    this.expirieddate = date;
}

c.create = function()
{
    if(this.currentdate == null) this._setCurrentDate();
    if(this.today == null) this.setToday(null, null, null);
    if(this.firstdate == null) this.setFirstDate(this.today.year, this.today.month+1, 1);
    if(this.lastdate == null)
    {
        var t = this._createDate(this.today.year, this.today.month + 13);
        t.date = this._getDaysCount(t.year, t.month);
        this.setLastDate(t.year, t.month, t.date);
    }
    if(this.expirieddate == null) this.setExpiried(null);

    if(this.activemonth == null) this.setActiveMonth(this.currentdate.year, this.currentdate.month);
    var diff = this._getMonthDiff(this.firstdate, this.lastdate);
    if(diff == 0) {
        this.activemonth = this.lastdate = this.firstdate;
        this.setStyle('single');
    }

    this._setButtons();
    var els = this._getElements("main");
    var el2 = this._createMonthLayout();
    els[0].appendChild(el2);
    els[0].obj = this;

    var x = -150 * this._getMonthDiff(this.firstdate, this.activemonth);
    els[0].style.left = x;
    this.lastx = x;
    this.maindiv = els[0];

    els = this._getElements("calendarContainer");
    els[0].calendar = this;
    if(document.body.calculators == null)
        document.body.calculators = [];
    document.body.calculators.push(this.divId);
    if (window.addEventListener) window.addEventListener("click", this._hide, false)
    else if (document.body.attachEvent) document.body.attachEvent("onclick", this._hide)
    else document.body.onclick = this._hide;
    this.created = true;
};

c._setCurrentDate = function()
{
    var d = new Date();
    this.currentdate = new Object();
    this.currentdate.year = d.getFullYear();
    this.currentdate.month = d.getMonth();
    this.currentdate.date = d.getDate();
};

c._setEvents = function(el)
{
    el.onclick = this._onDateSelect;
    el.onmouseover = this._dateSetOver;
    el.onmouseout = this._dateSetOver;
};

c._onDateSelect  = function(ev)
{
    var _this = this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.obj; // div class "_this"
    if(_this.selectedItem) {
        if(_this.selectedItem.className == 'dateCellTodaySelected') _this.selectedItem.className = 'dateCellToday';
        else if(_this.selectedItem.itemToday) _this.selectedItem.className = 'dateCellTodaySelected';
        else _this.selectedItem.className = 'dateCell';
        _this.selectedItem.itemSelected = false;
    }
    this.className = 'dateCellSelected';
    this.itemSelected = true;
    _this.selectedItem = this;
    var month = this.parentNode.parentNode.parentNode.month;
    var year = this.parentNode.parentNode.parentNode.year;

    var td = _this._createDate(parseInt(year), parseInt(month), parseInt(this.innerHTML))
    td = _this._getDay(td);
    if(document.body.lastInput) {
        var el = document.getElementById(document.body.lastInput);
        el.cdate = td;
        if(el.io.field) {
            eval('el.' + el.io.field + " = _this._dateToString('" + el.io.format + "', td);");
            if(el.io.affect) {
                for(var i in el.io.affect)
                {
                    var el2 = document.getElementById(el.io.affect[i].id);
                    eval('el2.' + el.io.affect[i].field + " = _this._dateToString('" + el.io.affect[i].format + "', td);");
                }

            }
        }
    }
    if(_this.closeOnSelect == true) _this.divObj.style.display = 'none';
};

c._dateSetOver = function(ev)
{
    var ev = window.event || ev;
    var target=window.event? window.event.srcElement: ev.target;
    switch(ev.type)
    {
        case 'mouseover' :
            this.className = 'dateCellHover';
            break;
        case 'mouseout' :
            if(target.itemSelected == true)
            {
                if(this.itemToday) this.className = 'dateCellTodaySelected';
                else this.className = 'dateCellSelected';
            }
            else
            {
                if(this.itemToday) this.className = 'dateCellToday';
                else this.className = 'dateCell';
            }
        break;
    }
};

c._getMonthDiff = function(date1, date2)
{
    var lastmonth = date1.month, c = 0;
    for(var i=date1.year; i<=date2.year; i++)
    {
        for(var j= lastmonth; j< 12; j++)
            if(i == date2.year && j == date2.month)
                return c;
            else c++;
        lastmonth = 0;
    }
    return c;
};

c._setButtons = function()
{
    var _date;
    var diff = this._getMonthDiff(this.firstdate, this.activemonth);
    if(diff == 0) {
        this._disableButton(this.leftButton, true);
    }
    else this._disableButton(this.leftButton, false);
    diff = this._getMonthDiff(this.activemonth, this.lastdate);
    if(this.style == 'double' && diff <= 1) this._disableButton(this.rightButton, true);
    else if(this.style == 'single' && diff == 0) this._disableButton(this.rightButton, true);
    else this._disableButton(this.rightButton, false);
};

c._createDate = function(year, month, date)
{
    if(date != null) {
        var c = this._getDaysCount(year, month, date);
        if(date > c) {
            date = 1;
            month ++;
        }
        else if(date < 1) {
            date = c;
            month --;
        }
    }

    if(month > 11) {
        month %= 11;
        month -= 1;
        year ++;
    }
    else if(month < 0) {
        month %= 11;
        month -= 1;
        if(month < 0) month += 13;
        year --;
    }
    var o = new Object();
    o.year = year;
    o.month = month;
    if(date != null) o.date = date;
    return o;
};

c._disableButton = function(elem, disable)
{
    if(disable == true) elem.style.display = 'none';
    else elem.style.display = 'block';
};

c._makeDivId = function()
{
    var l = 'CalendarSetadayVersion141';
    var divIdLen = 10;
    var i, div = '';
    while(true)
    {
        for(i=0; i<divIdLen; i++)
        {
            var index = Math.round(Math.random() * l.length);
            div += l.substr(index, 1);
        }
        if(! document.getElementById(div)) break;
    }
    return div;
};

c._createSkeleton = function()
{
var b = "<div id=\"" + this.divId + "\" class=\"calendarContainer\"><div class=\"headerBg\">&nbsp;</div><div><div class=\"leftButton\"><div class=\"leftButtonInput\">&nbsp;</div></div><div class=\"rightButton\"><div class=\"rightButtonInput\">&nbsp;</div></div></div><div class=\"main\" style=\"width: 10000px\"></div><div class=\"footer\">Close</div></div>";
    document.write(b);
    this.divObj = document.getElementById(this.divId);
    var b;

    b = this._getElements('footer');
    b[0].onmouseover = this._buttonSetOver;
    b[0].onmouseout = this._buttonSetOver;
    b[0].obj = this;
    b[0].onclick = this.close;

    b = this._getElements('leftButtonInput');
    b[0].onclick = this._scroll;
    b[0].onmouseover = this._buttonSetOver;
    b[0].onmouseout = this._buttonSetOver;
    this.leftButton = b[0];
    b[0].obj = this;

    b = this._getElements('rightButtonInput');
    b[0].onclick = this._scroll;
    b[0].onmouseover = this._buttonSetOver;
    b[0].onmouseout = this._buttonSetOver;
    this.rightButton = b[0];
    b[0].obj = this;

};

c._createMonthLayout = function()
{
    var d = new Date();
    var headers = bodies = '';
    var firstmonth = this.firstdate.month, lastmonth;
    var table = document.createElement('TABLE');
    table.setAttribute('class', 'monthLayout');
    table.setAttribute('className', 'monthLayout');
    table.setAttribute('height', '170px');
    table.setAttribute('border', '0');
    row = this._adr(table, '', 0);
    row.setAttribute('vAlign', 'top');
    var k = 0;
    for(var i=this.firstdate.year; i<= this.lastdate.year; i++)
    {
        if(i == this.lastdate.year) lastmonth = this.lastdate.month;
        else lastmonth = 11;
        for(j= firstmonth; j<= lastmonth; j++)
        {
            var e = this._addMonth(i, j);
            col = this._adc(row, '', '', k++);
            col.appendChild(e);
        }
        firstmonth = 0;
    }
    return table;
};



c._addMonth = function(year, month)
{
    var str = '';
    var date = { year: year, month: month }
    var header = this._dateToString(this.monthHeaderFormat, date)
    var r, c;

    var t = document.createElement('TABLE');
    t.setAttribute('class', 'monthForm');
    t.setAttribute('className', 'monthForm');
    t.setAttribute('width', '150px');
t.setAttribute('id', this.divId + this._dateToString("%y%M", date));
    t.month = month;
    t.year = year;
    r = this._adr(t, 'header', 0);
    c = this._adc(r, 'header', header, 0);
    c.setAttribute('colSpan', 7);
    r = this._adr(t, 'weeksrow', 1);
    for(i in caledarShortDays) this._adc(r, 'dayofweek', caledarShortDays[i].substr(0, 1), i);
    var i = 0, j = 2, cnt = 0, k = 0;
    var count =  this._getDaysCount(year, month);
    var first = this._getFirstMonthDay(year, month);
    var currentmonth = (year == this.currentdate.year && month == this.currentdate.month ? true : false);
    var todaymonth = false;
    if(this.today.year == year && this.today.month == month) todaymonth = true;
    var expired = (year <= this.expirieddate.year && month <= this.expirieddate.month ? true : false);


    while(true) {
        if(!(i % 8)) {
            r = this._adr(t, 'datesrow', j++);
            k = 0;
        }
        else {
            k++;
            if(i > first)
            {
                cnt ++;
                date = this._createDate(year, month, cnt);
                if(expired)
                {
                    if(cnt > this.expirieddate.date - 2) expired = false;
                    c = this._adc(r, 'dateCellExpired', cnt.toString(), k);
                }
                else if(todaymonth && cnt == this.today.date)
                {
                    expired = false;
                    if(currentmonth && cnt == this.today.date) {
                        c = this._adc(r, 'dateCellTodaySelected', cnt.toString(), k);
                        c.itemToday = true;
                        c.itemSelected = true;
                        this.selectedItem = c;
                        c.setAttribute('id', this.divId + this._dateToString("%y%M%D", date), k);
                        this._setEvents(c);
                    }
                    else {
                        c = this._adc(r, 'dateCellToday', cnt.toString(), k);
                        this._setEvents(c);
                        this.selectedItem = c;
                        c.setAttribute('id', this.divId + this._dateToString("%y%M%D", date), k);
                    }
                    todaymonth = false;
                }
                else if(currentmonth && cnt == this.today.date) {
                    c = this._adc(r, 'dateCellSelected', cnt.toString(), k);
                    c.itemSelected = true;
                    this.selectedItem = c;
                    c.setAttribute('id', this.divId + this._dateToString("%y%M%D", date), k);
                    this._setEvents(c);
                }
                else {
                    c = this._adc(r, 'dateCell', cnt.toString(), k);
                    c.setAttribute('id', this.divId + this._dateToString("%y%M%D", date), k);
                    this._setEvents(c);
                }
            }
            else c = this._adc(r, 'dateCellEmpty', '', k);
        }
        if(cnt >= count) break;
        i++;
    }
    return t;
};

c._adr = function(t, c, i) {
    r = t.insertRow(i);
    if(c!=null) r.setAttribute('class', c);
    if(c!=null) r.setAttribute('className', c);
    return r;
}

c._adc = function(r, c, ir, i) {
    i=r.childNodes.length;
    a = r.insertCell(i);
    a.setAttribute('class', c);
    a.setAttribute('className', c);
    if(ir!=null) a.innerHTML = ir;
    return a;
}

c._dateToString = function(format, date)
{
    var tmp;
    if(date == null) date = this.date;
    if(date.date != null) {
        format = format.replace("%d", date.date);
        tmp = (date.date < 10) ? "0" : "";
        format = format.replace("%D", tmp+date.date);
    }
    if(date.year != null) {
        format = format.replace("%Y", date.year);
        tmp = date.year.toString();
        format = format.replace("%y", tmp.substring(2, 4));
    }
    if(date.month != null) {
        format = format.replace("%m", date.month);
        format = format.replace("%O", calendarMonth[date.month]);
        tmp = (date.month+1 < 10) ? "0" : "";
        format = format.replace("%M", tmp+(date.month+1));
        format = format.replace("%o", calendarShortMonth[date.month]);
    }
    if(date.day != null) {
        format = format.replace("%s", caledarShortDays[date.day]);
        format = format.replace("%l", caledarDays[date.day]);
    }
    return format;
};

c._getDay = function(date)
{
    var d = new Date();
    d.setYear(date.year);
    d.setMonth(date.month);
    d.setDate(date.date);
    date.day = d.getDay();
    return date;
}

c._isLeapYear = function(year)
{
    if(Math.abs((year) % 4) == 0) return true;
    return false;
};

c._getDaysCount = function(year, month)
{
    var days;
    if(this._isLeapYear(year)) days = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    else days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    return days[month];
};

c._getFirstMonthDay = function(year, month) // return : index;
{
    var days = 0;
    var ret = 5 * parseInt(year / 4, 10);
    if(year % 4 > 0) ret += 2 + (year % 4) - 1;
    ret += 5;
    for(i=0; i < month; i++) days += this._getDaysCount(this.year, i);
    return (ret + days) % 7;
};

c._scroll = function(ev)
{
    var x2;
    var A = Animation;
    var c = this.obj;

    var fs = [ A.bounceEaseOut, A.regularEaseIn, A.regularEaseOut, A.backEaseIn, A.backEaseOut, A.backEaseInOut, A.elasticEaseIn, A.elasticEaseOut, A.elasticEaseInOut, A.bounceEaseIn, A.bounceEaseInOut, A.regularEaseIn, A.regularEaseOut, A.regularEaseInOut, A.strongEaseIn, A.strongEaseOut, A.strongEaseInOut];
    if(this.className == 'leftButtonInput') {
        x2 = this.obj.lastx + 150;
        var diff = c._getMonthDiff(c.firstdate, c.activemonth);
        if(diff) c.activemonth = c._createDate(c.activemonth.year, c.activemonth.month-1);
    }
    else {
        x2 = this.obj.lastx - 150;
        var diff = c._getMonthDiff(c.activemonth, c.lastdate);
        if((c.style == 'double' && diff > 1) || (c.style == 'single' && diff > 0))
            c.activemonth = c._createDate(c.activemonth.year, c.activemonth.month + 1);
    }
    var a = new Animation(c.maindiv.style, 'left', fs[c.animation], c.lastx, x2, c.scrollduration, 'px');
    c.lastx = x2;
    a.start();
    c._setButtons();
};

c._buttonSetOver = function(ev)
{
    var ev = window.event || ev;
    var target=window.event? window.event.srcElement: ev.target;
    switch(ev.type)
    {
        case 'mouseover' : target.style.cursor = 'pointer'; break;
        case 'mouseout' : target.style.cursor = 'default'; break;
    }

};

c._setSelectedDate = function(y, m, d)
{
    if(this.created) {
        var date = this._createDate(y, m, d);
        var id = this.divId + this._dateToString("%y%M%D", date);
        if(id != this.selectedItem.id)
        {

            var el = document.getElementById(id);
            if(el.className == 'dateCell') {
                el.className = 'dateCellSelected';
            }
            else if(el.className == 'dateCellToday') {
                el.className = 'dateCellTodaySelected';
            }
            el.itemSelected = true;
            if(this.selectedItem.className == 'dateCellSelected') this.selectedItem.className = 'dateCell';
            else if(this.selectedItem.className == 'dateCellTodaySelected') this.selectedItem.className = 'dateCellToday';
            this.selectedItem = el;

            var diff = this._getMonthDiff(this.firstdate, date);
            this.activemonth = this._createDate(this.firstdate.year, this.firstdate.month + diff);
            if(this.style == 'double' && this.activemonth.year == this.lastdate.year && this.activemonth.month == this.lastdate.month) diff --;
            var x = -150 * diff;
            this.maindiv.style.left = x;
            this.lastx = x;
        }
    }
}

c._show = function(ev)
{
    var ev = window.event || ev;
    var calendar = document.getElementById(this.calendar.divId);
    var coord = getPageCoords(this);
    var left, top;

    if(this.cdate != null) this.calendar._setSelectedDate(this.cdate.year, this.cdate.month, this.cdate.date);

    if(typeof this.io.halign == 'undefined' || this.io.halign == '') this.io.halign = 'left';
    if(typeof this.io.valign == 'undefined' || this.io.valign == '') this.io.valign = 'top';

    if(this.halign == 'mouse')
    {
        if(ev.type == 'focus') left = coord.x
        else left = ev.clientX;
    }
    else if(this.io.halign == 'left') left = coord.x;
    else if(this.io.halign == 'right') left = coord.x + this.offsetWidth;

    if(this.halignY == 'mouse')
    {
        if(ev.type == 'focus') top = coord.y + this.offsetHeight;
        else top = ev.clientY;
    }
    else if(this.io.valign == 'top') top = coord.y;
    else if(this.io.valign == 'bottom') top = coord.y + this.offsetHeight;

    if(typeof this.io.offsetLeft != 'undefined') left += this.io.offsetLeft;
    if(typeof this.io.offsetTop != 'undefined') top += this.io.offsetTop;
	
	calendar.style.left = left + 'px';
    calendar.style.top = top + 'px';
    this.calendar.show();
    this.calendar._setButtons();
    document.body.lastInput = this.id;
};

c._hide = function(ev) {
    var ev = window.event || ev;
    var target=window.event? window.event.srcElement: ev.target;
    if(document.body.lastInput == target.id) return;
    for(var i= 0; i< document.body.calculators.length; i++)
    {
        if(! hasId(target, document.body.calculators[i]))
            document.getElementById(document.body.calculators[i]).style.display = 'none';
    }
}

function hasId(node, id) {
    while(node) {
        if(node.id == id) return true;
        node = node.parentNode;
    }
    return false;
}

c._getElements = function(searchClass, tag, parentClass)
{
    var classElements = new Array();
    if ( tag == null ) tag = '*';
    var els = document.getElementsByTagName(tag);
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
    for (i = 0, j = 0; i < elsLen; i++)
    {
        if ( pattern.test(els[i].className) )
        {
            var temp = els[i];
            while(temp)
            {
                if(temp.id == this.divObj.id)
                {
                    if(parentClass != null && parentClass != els[i].parentNode.className) break;
                    classElements[j] = els[i];
                    j++;
                    break;
                }
                temp = temp.parentNode;
            }
        }
    }
    return classElements;
};

function getPageCoords (element) {
    var coords = { x: 0, y: 0 };
    while (element)
    {
        coords.x += element.offsetLeft;
        coords.y += element.offsetTop;
        element = element.offsetParent;
    }
    return coords;
};

/************ animation js *****************/
function Delegate() {}
Delegate.create = function (o, f) {
	var a = new Array() ;
	var l = arguments.length ;
	for(var i = 2 ; i < l ; i++) a[i - 2] = arguments[i] ;
	return function() {
		var aP = [].concat(arguments, a) ;
		f.apply(o, aP);
	}
};

Animation = function(obj, prop, func, begin, finish, duration, suffixe){
	this.init(obj, prop, func, begin, finish, duration, suffixe)
};
var t = Animation.prototype;

t.obj = new Object();
t.prop='';
t.func = function (t, b, c, d) { return c*t/d + b; };
t.begin = 0;
t.change = 0;
t.prevTime = 0;
t.prevPos = 0;
t.looping = false;
t._duration = 0;
t._time = 0;
t._pos = 0;
t._position = 0;
t._startTime = 0;
t._finish = 0;
t.name = '';
t.suffixe = '';
t._listeners = new Array();
t.setTime = function(t){
	this.prevTime = this._time;
	if (t > this.getDuration()) {
		if (this.looping) {
			this.rewind (t - this._duration);
			this.update();
			this.broadcastMessage('onMotionLooped',{target:this,type:'onMotionLooped'});
		} else {
			this._time = this._duration;
			this.update();
			this.stop();
			this.broadcastMessage('onMotionFinished',{target:this,type:'onMotionFinished'});
		}
	} else if (t < 0) {
		this.rewind();
		this.update();
	} else {
		this._time = t;
		this.update();
	}
};
t.getTime = function(){
	return this._time;
};
t.setDuration = function(d){
	this._duration = (d == null || d <= 0) ? 100000 : d;
};
t.getDuration = function(){
	return this._duration;
};
t.setPosition = function(p){
	this.prevPos = this._pos;
	var a = this.suffixe != '' ? this.suffixe : '';
	this.obj[this.prop] = Math.round(p) + a;
	this._pos = p;
	this.broadcastMessage('onMotionChanged',{target:this,type:'onMotionChanged'});
};
t.getPosition = function(t){
	if (t == undefined) t = this._time;
	return this.func(t, this.begin, this.change, this._duration);
};
t.setFinish = function(f){
	this.change = f - this.begin;
};
t.geFinish = function(){
	return this.begin + this.change;
};
t.init = function(obj, prop, func, begin, finish, duration, suffixe){
	if (!arguments.length) return;
	this._listeners = new Array();
	this.addListener(this);
	if(suffixe) this.suffixe = suffixe;
	this.obj = obj;
	this.prop = prop;
	this.begin = begin;
	this._pos = begin;
	this.setDuration(duration);
	if (func!=null && func!='') {
		this.func = func;
	}
	this.setFinish(finish);
};
t.start = function(){
	this.rewind();
	this.startEnterFrame();
	this.broadcastMessage('onMotionStarted',{target:this,type:'onMotionStarted'});
	//alert('in');
};
t.rewind = function(t){
	this.stop();
	this._time = (t == undefined) ? 0 : t;
	this.fixTime();
	this.update();
};
t.fforward = function(){
	this._time = this._duration;
	this.fixTime();
	this.update();
};
t.update = function(){
	this.setPosition(this.getPosition(this._time));
};
t.startEnterFrame = function(){
	this.stopEnterFrame();
	this.isPlaying = true;
	this.onEnterFrame();
};
t.onEnterFrame = function(){
	if(this.isPlaying) {
		this.nextFrame();
		setTimeout(Delegate.create(this, this.onEnterFrame), 0);
	}
};
t.nextFrame = function(){
	this.setTime((this.getTimer() - this._startTime) / 1000);
};
t.stop = function(){
	this.stopEnterFrame();
	this.broadcastMessage('onMotionStopped',{target:this,type:'onMotionStopped'});
};
t.stopEnterFrame = function(){
	this.isPlaying = false;
};

t.continueTo = function(finish, duration){
	this.begin = this._pos;
	this.setFinish(finish);
	if (this._duration != undefined)
		this.setDuration(duration);
	this.start();
};
t.resume = function(){
	this.fixTime();
	this.startEnterFrame();
	this.broadcastMessage('onMotionResumed',{target:this,type:'onMotionResumed'});
};
t.yoyo = function (){
	this.continueTo(this.begin,this._time);
};

t.addListener = function(o){
	this.removeListener (o);
	return this._listeners.push(o);
};
t.removeListener = function(o){
	var a = this._listeners;
	var i = a.length;
	while (i--) {
		if (a[i] == o) {
			a.splice (i, 1);
			return true;
		}
	}
	return false;
};
t.broadcastMessage = function(){
	var arr = new Array();
	for(var i = 0; i < arguments.length; i++){
		arr.push(arguments[i])
	}
	var e = arr.shift();
	var a = this._listeners;
	var l = a.length;
	for (var i=0; i<l; i++){
		if(a[i][e])
		a[i][e].apply(a[i], arr);
	}
};
t.fixTime = function(){
	this._startTime = this.getTimer() - this._time * 1000;
};
t.getTimer = function(){
	return new Date().getTime() - this._time;
};
Animation.backEaseIn = function(t,b,c,d,a,p){
	if (s == undefined) var s = 1.70158;
	return c*(t/=d)*t*((s+1)*t - s) + b;
};
Animation.backEaseOut = function(t,b,c,d,a,p){
	if (s == undefined) var s = 1.70158;
	return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
};
Animation.backEaseInOut = function(t,b,c,d,a,p){
	if (s == undefined) var s = 1.70158;
	if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
	return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
};
Animation.elasticEaseIn = function(t,b,c,d,a,p){
   if (t==0) return b;
   if ((t/=d)==1) return b+c;
   if (!p) p=d*.3;
   if (!a || a < Math.abs(c)) {
   	a=c; var s=p/4;
   }
   else var s = p/(2*Math.PI) * Math.asin (c/a);
   return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;

};
Animation.elasticEaseOut = function (t,b,c,d,a,p){
	if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
	if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
	else var s = p/(2*Math.PI) * Math.asin (c/a);
	return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
};
Animation.elasticEaseInOut = function (t,b,c,d,a,p){
	if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) var p=d*(.3*1.5);
	if (!a || a < Math.abs(c)) {var a=c; var s=p/4; }
	else var s = p/(2*Math.PI) * Math.asin (c/a);
	if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
};

Animation.bounceEaseOut = function(t,b,c,d){
	if ((t/=d) < (1/2.75)) {
		return c*(7.5625*t*t) + b;
	} else if (t < (2/2.75)) {
		return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
	} else if (t < (2.5/2.75)) {
		return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
	} else {
		return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
	}
};
Animation.bounceEaseIn = function(t,b,c,d){
	return c - Animation.bounceEaseOut (d-t, 0, c, d) + b;
};
Animation.bounceEaseInOut = function(t,b,c,d){
	if (t < d/2) return Animation.bounceEaseIn (t*2, 0, c, d) * .5 + b;
	else return Animation.bounceEaseOut (t*2-d, 0, c, d) * .5 + c*.5 + b;
};

Animation.strongEaseInOut = function(t,b,c,d){
	return c*(t/=d)*t*t*t*t + b;
};

Animation.regularEaseIn = function(t,b,c,d){
	return c*(t/=d)*t + b;
};
Animation.regularEaseOut = function(t,b,c,d){
	return -c *(t/=d)*(t-2) + b;
};

Animation.regularEaseInOut = function(t,b,c,d){
	if ((t/=d/2) < 1) return c/2*t*t + b;
	return -c/2 * ((--t)*(t-2) - 1) + b;
};
Animation.strongEaseIn = function(t,b,c,d){
	return c*(t/=d)*t*t*t*t + b;
};
Animation.strongEaseOut = function(t,b,c,d){
	return c*((t=t/d-1)*t*t*t*t + 1) + b;
};

Animation.strongEaseInOut = function(t,b,c,d){
	if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
	return c/2*((t-=2)*t*t*t*t + 2) + b;
};
