/* vim: set tabstop=2 shiftwidth=2 foldmethod=marker: */
/**
 * 
 * ska.js - JavaScript 便利フレームワーク(?)
 *
 * @author      SHOGO <shogo@studiofly.net>
 * @copyright   2005-2007 studiofly software
 * @version     CVS: $Id: ska.js,v 1.6 2007/07/06 06:29:36 shogo Exp $
 *
 */
/** 高速$関数 **/
$.cache = {};
function $(e) {
	if (typeof(e) == 'string') {
		return $.cache[e] || ($.cache[e] = Element.extend(document.getElementById(e)));
	}
	return Element.extend(e);
}

/** メインオブジェクト (兼名前空間) **/
var ska = {
	debug: true,
	// bodyオブジェクトを返す
	body: function()
	{
		if (ska.ua.msie) {
			return document[(document.compatMode == 'CSS1Compat') ? 'documentElement' : 'body'];
		} else if (ska.ua.gecko || ska.ua.khtml) {
			return document.documentElement;
		}
		return document.body;
	},
	// デバッグ情報出力
	log: function(msg)
	{
		if (ska.ua.opera) {
			opera.postError(msg);
		} else if (window.console && (ska.ua.safari || ska.ua.firefox)) {
			window.console.log(msg);
		} else {
			alert(msg);
		}
	}
};

/** ブラウザ判別オブジェクト **/
ska.ua = {
	/** プロパティ */
	msie:      false,
	opera:     false,
	safari:    false,
	konqueror: false,
	khtml:     false,
	gecko:     false,
	firefox:   false,
	mozilla:   false,
	
	// ユーザーエージェント判別
	detect: function()
	{
		// USER_AGENT取得
		var ua = navigator.userAgent.toLowerCase();
		
		// USER_AGENT判別
		if (window.opera) {
			this.opera = true;
		} else if (ua.indexOf('msie') != -1) {
			this.msie = true;
		} else if (ua.indexOf('applewebkit/') != -1) {
			this.khtml = this.safari = true;
		} else if (ua.indexOf('konqueror/') != -1) {
			this.khtml = this.konqueror = true;
		} else if (ua.indexOf('khtml/') != -1) {
			this.khtml = true;
		} else if (ua.indexOf('firefox/') != -1) {
			this.gecko = this.mozilla = this.firefox = true;
		} else if (ua.indexOf('gecko/') != -1) {
			this.gecko = this.mozilla = true;
		} else if (ua.indexOf('mozilla/') != -1) {
			this.mozilla = true;
		}
	},
	// 文字列化
	toString: function(){
		return navigator.userAgent;
	}
};
ska.ua.detect();

/** Ajax.Updater改造版 **/
ska.updater = Class.create();
Object.extend(ska.updater.prototype, Ajax.Request.prototype)
Object.extend(ska.updater.prototype, {
	// 送信処理
	initialize: function(container, url, options)
	{
		this.container = container;
		this.transport = Ajax.getTransport();
		this.setOptions(options);
		
		var onComplete = this.options.onComplete || Prototype.emptyFunction;
		this.options.onComplete = (function(transport, object) {
			this.updateContent();
			onComplete(transport, object);
		}).bind(this);
		
		var date = new Date();
		this.request(url + (url.match(/\?/) ? '&' : '?') + date.getTime());
	},
	// リクエスト中断
	abort: function()
	{
		var conn = this.transport;
		if (conn && conn.readyState && (conn.readyState != 4)) {
			conn.abort();
			Ajax.Responders.dispatch('onComplete', this);
		}
	},
	// HTML更新処理
	updateContent: function()
	{
		var receiver = this.container;
		var element  = $(receiver);
		if (element) {
			$.cache = {};
			this._updateContent(element, this.transport.responseText);
		}
	},
	// HTML更新処理(IE/Gecko/その他)
	_updateContent: function(element, text) {
		return element.update(text);
	}
});
if (ska.ua.khtml) {
	// HTML更新処理(KHTML)
	naruto.updater.prototype._updateContent = function(element, text)
	{
		window.scrollTo(0, 0);
		var esc = escape(text);
		return element.update(
			esc.indexOf("%u") < 0 && esc.indexOf("%") > -1 ? decodeURIComponent(esc) : text
			);
		element.hide();
		setTimeout(function(){ element.show(); }, 100);
	};
}

/** ドキュメントクラス **/
ska.document = Class.create();
Object.extend(ska.document.prototype, {
	// 初期化
	initialize: function(element)
	{
		element = $(element);
		$A(element.getElementsByTagName('a')).each(function(e){ ska.anchor.init(e); });
		$A(element.getElementsByTagName('form')).each(function(e){ ska.form.init(e); });
	}
});
ska.anchor = {
	init: function(element)
	{
		var a = $(element);
		if (!a) return;
		if (a.hasClassName('ajax')) {
			Event.observe(a, 'click', this.ajax.bindAsEventListener(a), true);
		} else if (a.hasClassName('lbOn')) {
			Event.observe(a, 'click', this.lbOn.bindAsEventListener(a), true);
		}
		return false;
	},
	ajax: function(event)
	{
		Event.stop(event);
		if (this.hasClassName('confirm') && !confirm(this.title + 'よろしいですか？')) {
			return false;
		}
		new ska.updater(this.target || 'main', this.href, {method: 'get'});
		return false;
	},
	lbOn: function(event)
	{
		Event.stop(event);
		ska.lbImage.show(a.href, a.title);
		return false;
	}
};
ska.form = {
	init: function(element)
	{
		var form = $(element);
		if (form.hasClassName('ajax')) {
			Event.observe(form, 'submit', this.ajax.bindAsEventListener(form), true);
		}
		if (form.hasClassName('focus')) {
			Form.focusFirstElement(form);
		}
	},
	ajax: function(event)
	{
		Event.stop(event);
		var form = this;
		if (form._notice && !confirm(form._notice.value)) {
			return false;
		}
		new ska.updater(form.target || 'main', form.action, {method: form.method, parameters: Form.serialize(form)});
	}
};

/** 選択範囲処理クラス **/
ska.selection = Class.create();
Object.extend(ska.selection.prototype, {
	start:  null,
	end:    null,
	text:   null,
	length: null,
	
	initialize: function(element)
	{
		element = $(element);
		if (!element || (element.type != 'textarea')) {
			return false;
		} else if (!isNaN(element.selectionEnd)) {
			this.start  = element.selectionStart;
			this.end    = element.selectionEnd;
			this.text   = element.value.substring(this.start, this.end);
			this.length = this.end - this.start;
		} else if (document.selection) {
			element.focus();
			var range    = document.selection.createRange();
			var bookmark = range.getBookmark();
			var original = element.value;
			var marker   = String.fromCharCode(0x1F, 0x1F);
			
			this.text   = String(range.text);
			this.length = this.text.length;
			
			range.text = marker + range.text + marker;
			var text   = element.value;
			this.start = text.indexOf(marker);
			this.end   = text.replace(marker, '').indexOf(marker);
			
			element.value = original;
			range.moveToBookmark(bookmark);
			range.select();
		}
	}
});

/** lightbox風ツール群 **/
ska.lb = {
	element: null,
	scroll:  false,
	
	init: function()
	{
		if (this.element) return false;
		var obj = $('ska_lb');
		if (obj) { this.element = obj; return false; }
		
		obj = $(document.createElement('div'));
		obj.setAttribute('id', 'ska_lb');
		obj.hide();
		var body = document.getElementsByTagName('body')[0];
		body.insertBefore(obj, body.firstChild);
		this.element = obj;
	},
	show: function(width, height)
	{
		var body = ska.body();
		var node = this.element;
		node.setStyle({width: width, height: height, visibility: 'hidden', display: 'block'});
		var left = Math.floor((body.clientWidth - node.offsetWidth) / 2 + body.scrollLeft);
		var top  = Math.floor((body.clientHeight - node.offsetHeight) / 2 + body.scrollTop);
		if (left < 0) left = 0;
		if (top < 0) top = 0;
		node.setStyle({
			left:       left + 'px',
			top:        top + 'px',
			visibility: 'visible',
			overflowY:   ska.lb.scroll ? 'scroll' : 'hide'
			});
		ska.overlay.element.onclick = function() { ska.lb.hide(); };
	},
	hide: function()
	{
		this.element.hide();
		this.element.update('');
		ska.overlay.hide();
		ska.overlay.element.onclick = function(){ ska.overlay.hide(); };
	},
	update: function(html)
	{
		this.element.innerHTML = html;
	},
	open: function(url, width, height)
	{
		if (!this.element) this.init();
		ska.overlay.show();
		var options = {method: 'get', onComplete: function(){ ska.lb.show(width, height); }};
		new ska.updater('ska_lb', url, options);
	},
	close: function()
	{
		return this.hide();
	}
};
ska.lbImage = {
	img: null,
	init: function()
	{
		ska.lb.init();
		this.img = new Image();
		this.img.onload = this.onload.bind(this);
	},
	onload: function()
	{
		var html   = '';
		var title  = this.img.alt;
		var width  = this.img.width;
		var height = this.img.height;
		if (width > 800) {
			height = Math.round(height * (800 / width));
			width  = 800;
		}
		html += '<div id="ska_lb_img" onclick="ska.lb.hide();">';
		html += '<div id="ska_lb_title">' + title + '</div>';
		html += '<div id="ska_lb_hint">click to close</div>';
		html += '<img src="' + this.img.src + '"';
		html += ' width="' + width + '"';
		html += ' height="' + height + '"';
		html += ' alt="' + title + '" /></div>';
		ska.lb.update(html);
		ska.lb.show('auto', 'auto');
	},
	show: function(src, alt)
	{
		if (!this.img) this.init();
		ska.overlay.show();
		ska.lb.scroll = false;
		this.img.alt  = alt;
		this.img.src  = src;
	}
};

/** オーバーレイ処理 **/
ska.overlay = {
	element: null,
	init: function()
	{
		if (this.element) return false;
		var div = $('ska_overlay');
		if (div) { this.element = div; return false; }
		
		div = $(document.createElement('div'));
		div.setAttribute('id', 'ska_overlay');
		div.hide();
		var body = document.getElementsByTagName('body')[0];
		body.insertBefore(div, body.firstChild);
		this.element = div;
		div.onclick = function(){ ska.overlay.hide(); };
	},
	show: function()
	{
		if (!this.element) this.init();
		if (ska.ua.msie) {
			$A(document.getElementsByTagName('select')).each(function(e){$(e).hide();});
		}
		var body   = ska.body();
		var height = $A([body.scrollHeight, body.clientHeight, window.innerHeight]);
		this.element.setStyle({opacity: 0.75, height: height.max() + 'px', display: 'block'});
	},
	hide: function()
	{
		if (ska.ua.msie) {
			$A(document.getElementsByTagName('select')).each(function(e){$(e).show();});
		}
		this.element.hide();
	}
};
