/*!
  spica javascript libraries - spica.js
  == written by Takuya Otani <takuya.otani@gmail.com> ===
  == Copyright (C) 2006 SimpleBoxes/SerendipityNZ Ltd. ==
*/

// [guideline]
// -- http://serennz.sakura.ne.jp/guidelines/js_en_000.txt
// -- http://serennz.sakura.ne.jp/guidelines/js_ja_000.txt

// ver 0.01 [2008/11/17] modified Spica.Library to handle lib correctly
// ver 0.00 [2008/11/01] the first attempt (re-version)

// === array basic fuctionalities ===
if (!Array.prototype.pop)
{
	Array.prototype.pop = function()
	{
		if (!this.length) return null;
		var last = this[this.length - 1];
		--this.length;
		return last;
	}
}
if (!Array.prototype.push)
{
	Array.prototype.push = function()
	{
		for (var i=0,n=arguments.length;i<n;i++)
			this[this.length] = arguments[i];
		return this.length;
	}
}
if (!Array.prototype.indexOf)
{
	Array.prototype.indexOf = function(value,idx)
	{
		idx = (typeof idx != 'number') ? 0
		    : (idx < 0)                ? this.length + idx
		    :                            idx;
		for (var i=idx,n=this.length;i<n;i++)
			if (this[i] === value) return i;
		return -1;
	}
}
// === spica ===
if (!window.Spica) var Spica = {};
// === browser ===
Spica.Browser = new function()
{
	this.name = navigator.userAgent;
	this.isWinIE = this.isMacIE = false;
	this.isGecko = this.name.match(/Gecko\//);
	this.isSafari = this.name.match(/AppleWebKit/);
	this.isSafari3 = (this.name.match(/AppleWebKit\/(\d\d\d)/) && parseInt(RegExp.$1) > 500);
	this.isKHTML = this.isSafari || navigator.appVersion.match(/Konqueror|KHTML/);
	this.isOpera = window.opera;
	if (document.all && !this.isGecko && !this.isSafari && !this.isOpera)
	{
		this.isWinIE = this.name.match(/Win/);
		this.isMacIE = this.name.match(/Mac/);
		this.isNewIE = (this.name.match(/MSIE (\d\.\d)/) && RegExp.$1 > 6.5);
	}
};
// === event ===
Spica.Event = {
	cache : false,
	getKey : function(evnt)
	{
		if (!evnt) return; // do nothing
		return (evnt.keyCode) ? evnt.keyCode : evnt.charCode;
	},
	stop : function(evnt)
	{
		if (!evnt) return; // do nothing
		try
		{
			evnt.stopPropagation();
		}
		catch(err) {};
		evnt.cancelBubble = true;
		try
		{
			evnt.preventDefault();
		}
		catch(err) {};
		return (evnt.returnValue = false);
	},
	register : function(object, type, handler)
	{
		if (!object) return;
		if (type == 'keypress' && !object.addEventListener) type = 'keydown';
		if (type == 'mousewheel' && Spica.Browser.isGecko) type = 'DOMMouseScroll';
		if (!this.cache) this.cache = [];
		if (object.addEventListener)
		{
			this.cache.push([object,type,handler]);
			object.addEventListener(type, handler, false);
		}
		else if (object.attachEvent)
		{
			this.cache.push([object,type,handler]);
			object.attachEvent('on' + type,handler);
		}
		else
		{
			object['on' + type] = handler;
		}
	},
	deregister : function(object, type, handler)
	{
		if (!object) return;
		if (type == 'keypress' && !object.addEventListener) type = 'keydown';
		if (type == 'mousewheel' && Spica.Browser.isGecko) type = 'DOMMouseScroll';
		if (object.removeEventListener)
			object.removeEventListener(type, handler, false);
		else if (object.detachEvent)
			object.detachEvent('on' + type, handler);
		else
			object['on' + type] = null;
	},
	deregisterAll : function()
	{
		if (!Spica.Event.cache) return
		for (var i=0,n=Spica.Event.cache.length;i<n;i++)
		{
			Spica.Event.deregister(Spica.Event.cache[i]);
			Spica.Event.cache[i][0] = null;
		}
		Spica.Event.cache = false;
	},
	run : function(func)
	{
		if (typeof func != 'function') return;
		(Spica.Browser.isGecko || Spica.Browser.isOpera)
			? this.register(window,'DOMContentLoaded',func)
			: this.register(window,'load',func);
	}
};
Spica.Event.register(window, 'unload', Spica.Event.deregisterAll);
// === locale ===
Spica.StrData = {};
Spica.getLocalizedString = function(str)
{
	if (Spica.StrData[str] && Spica.StrData[str] != '')
		return Spica.StrData[str];
	return str;
};
Spica.$_ = Spica.getLocalizedString; // $_ is an alias of getLocalizedString
// === library ===
Spica.Library = function()
{
	this._cache = [];
	this._init = false;
	this.lang = 'en';
	this.rsrc = '';
	this.path = '';
	return this;
}
Spica.Library.prototype = {
	initialize : function()
	{
		if (this._init) return;
		var html = document.getElementsByTagName('html')[0];
		if (html)
		{
			var lang = html.getAttribute('xml:lang') || html.getAttribute('lang');
			if (lang) this.lang = lang;
		}
		var scripts = document.getElementsByTagName('script');
		for (var i=0,n=scripts.length;i<n;i++)
		{
			if (scripts[i].src.indexOf('spica.js') == -1) continue;
			this.path = scripts[i].src.replace('spica.js','');
			break;
		}
		var links = document.getElementsByTagName('link');
		for (var i=0,n=links.length;i<n;i++)
		{
			if (links[i].getAttribute('rel').indexOf('resource') == -1) continue;
			this.rsrc = this._check_path(links[i].getAttribute('href'));
			break;
		}
		this._init = true;
	},
	require : function()
	{
		if (!this._init) this.initialize();
		var pre  = '\n<' + 'script type="text/javascript" src="';
		var post = '.js"></' + 'script>';
		for (var i=0,n=arguments.length;i<n;i++)
		{
			var lib = arguments[i];
			lib = lib.replace(/\.js$/i,''); // get rid of extension
			if (this._cache.indexOf(lib) > -1) continue;
			document.write(pre + this.path + lib,post);
			this._cache.push(lib);
		}
		// we should load locale data if it has not been loaded.
		if (this.lang && this._cache.indexOf('locale/' + this.lang) == -1)
			this.require('locale/' + this.lang);
	},
	append : function()
	{
		if (!this._init) this.initialize();
		var head = document.getElementsByTagName('head')[0];
		for (var i=0,n=arguments.length;i<n;i++)
		{
			var lib = arguments[i];
			lib = lib.replace(/\.js$/i,''); // get rid of extension
			if (this._cache.indexOf(lib) > -1) continue;
			var script = document.createElement('script');
			script.setAttribute('type','text/javascript');
			script.setAttribute('src',this.path + lib + '.js');
			this._cache.push(lib);
			head.appendChild(script);
		}
	},
	_check_path : function(path)
	{
		if (!path) return '';
		if (!path.match(/\/$/)) path = path + '/';
		return path;
	}
}
Spica.Library = new Spica.Library();
Spica.Event.run(function() { Spica.Library.initialize(); });


