/* section.js */

/* rgb.js
 * Copyright (C) 2006 Hiroyuki KUROSAKI <noir (at) st.rim.or.jp>
 */

/* require: prototype.js (1.4.0) */

/* some utility methods for built-ins */

Number.prototype.toHex = function(padding) {
    var s = this.toString(16);
    var zp = new Array();
    var padlen = padding - s.length;
    for (var i = 0; i < padlen; i++) {
	zp.push("0");
    }
    return zp.join("") + s;
}

String.prototype.toRGBValue = function() {
    return this.match(/[0-9a-fA-F]{2}/g).map(function(x) {
	    return parseInt("0x" + x);
	});
}

Array.prototype.clone = function() {
    return Array.apply(null, this);
}

var RGB = Class.create();

RGB.MIN_VALUE = 0;
RGB.MAX_VALUE = 0xff;

RGB.prototype = {
    initialize: function(value) {
	if (typeof value == "string") {
	    this.value = value.toRGBValue();
	}
	else if (typeof value == "object" && value.constructor == Array) {
	    this.value = value.clone();
	}
	else {
	    this.value = [0, 0, 0];
	}
    },
    r: function() {
	return this.value[0];
    },
    g: function() {
	return this.value[1];
    },
    b: function() {
	return this.value[2];
    },
    toString: function() {
	return "#" + this.value.map(function(x) { return x.toHex(2); }).join("");
    },
    clone: function() {
	return new RGB(this.value);
    },
    calculate: function(f, other) {
	if (other == undefined) {
	    other = new RGB();
	}
	return new RGB(this.value.zip(other.value).map(function(v) {
		    var nv = f(v[0], v[1]);
		    if (nv > RGB.MAX_VALUE) {
			return RGB.MAX_VALUE;
		    }
		    else if (nv < RGB.MIN_VALUE) {
			return RGB.MIN_VALUE;
		    }
		    else {
			return nv;
		    }
		}));
    },
    add: function(other) {
	return this.calculate(function(x, y) { return x + y; }, other);
    },
    sub: function(other) {
	return this.calculate(function(x, y) { return x - y; }, other);
    },
    compare: function(f, other) {
	return this.value.zip(other.value).inject(true, function(m, v) {
		return m && f(v[0], v[1]);
	    });
    },
    ge: function(other) {
	return this.compare(function(x, y) { return x >= y; }, other);
    },
    gt: function(other) {
	return this.compare(function(x, y) { return (x > y || x == RGB.MAX_VALUE); }, other);
    },
    le: function(other) {
	return this.compare(function(x, y) { return x <= y; }, other);
    },
    lt: function(other) {
	return this.compare(function(x, y) { return (x < y || y == RGB.MAX_VALUE); }, other);
    }
}

/* rgb.js end */

/* blink.js */

/* require: prototype.js (1.4.0), rgb.js */

var Blink = Class.create();

Blink.timerIds = new Array();

Blink.prototype = {
    initialize: function(elem, darkColor, lightColor, duration, frame) {
	this.elem = $(elem);
	this.darkColor = darkColor.clone();
	this.lightColor = lightColor.clone();
	this.stepColor = lightColor.sub(darkColor).calculate(function(x) {
	    return Math.round(x / frame);
	});
	this.interval = duration * 1000 / frame;
	this.elem.style.backgroundColor = darkColor.toString();
    },
    start: function() {
	if (Blink.timerIds[this.elem.id]) {
	    this.stop();
	}
	var currentColor = this.darkColor;
	var calcFunc = currentColor.add;
	Blink.timerIds[this.elem.id] = setInterval((function() {
	    if (currentColor.ge(this.lightColor)) {
		currentColor = this.lightColor.clone();
		calcFunc = currentColor.sub;
	    }
	    else if (currentColor.le(this.darkColor)) {
		currentColor = this.darkColor.clone();
		calcFunc = currentColor.add;
	    }
	    this.elem.style.backgroundColor = currentColor.toString();
	    currentColor = (calcFunc.bind(currentColor))(this.stepColor);
	}).bind(this), this.interval);
    },
    stop: function() {
	clearInterval(Blink.timerIds[this.elem.id]);
	delete Blink.timerIds[this.elem.id];
    }
}
 
/* blink.js end */

window.onload = function() {

    var recent = $("recentItem");
    var blink;
    if (recent) {
	blink = new Blink(recent,
			  new RGB([0xff, 0xff, 0x99]),
			  new RGB([0xff, 0xff, 0xff]),
			  1,
			  10);
	blink.start();
    }

}
