/**
 * sisso.js - 質素なWeb制作のためのJS
 *
 * Copyright (C) KAYAC Inc. | http://www.kayac.com/
 * Dual licensed under the MIT <http://www.opensource.org/licenses/mit-license.php>
 * and GPL <http://www.opensource.org/licenses/gpl-license.php> licenses.
 * Date: 2009-1-2
 * @author kyo_ago <http://tech.kayac.com/archive/iepngfix-library-sisso-js.html>
 * @version 1.0.3
 *
 * thanks from
 *   http://www.isella.com/aod2/js/iepngfix.js
 *   http://jquery.com/
 *   http://kyosuke.jp/portfolio/javascript/yuga.html
 */

;new function () {
	var name_space = 'Sisso';
	var self = window[name_space] || {};
	window[name_space] = self;
	self.overClass = self.overClass || 'btn';
	self.noRoll = self.noRoll || false;
	self.noFix = self.noFix || false;

	var $ = window.jQuery;
	var $d = document;

	self.get_elems = (function () {
		if ($d.getElementsByClassName) return function (cname) {
			return $d.getElementsByClassName(cname);
		};
		if ($d.querySelectorAll) return function (cname) {
			return $d.querySelectorAll('*.' + cname);
		};
		if ($d.evaluate) return function (cname) {
			var elems = $d.evaluate("descendant::*[@class=" + cname + " or contains(concat(' ', @class, ' '), ' " + cname + " ')]", $d, null, 7, null);
			var result = [];
			for (var i = 0, l = elems.snapshotLength; i < l; result.push(elems.snapshotItem(i++)));
			return result;
		};
		var self_cname = self.overClass;
		var reg = new RegExp('[ \\n\\r\\t]' + self_cname + '[ \\n\\r\\t]');
		return function (cname) {
			var elems = $d.body.getElementsByTagName('*');
			var result = [];
			for (var i = 0, l = elems.length; i < l; ++i) {
				var elem = elems[i];
				if (elem.className.indexOf(self_cname) == -1) continue;
				if (!reg.test(' ' + elem.className + ' ')) continue;
				result.push(elem);
			}
			return result;
		};
	})();

	self.get_src = function (elem) {
		if (elem.src) return elem.src;
		src = (elem.currentStyle || $d.defaultView.getComputedStyle(elem, '')).backgroundImage;
		return (src.match(/^url\((["']?)(.*\.png)\1\)$/i) || [undefined]).pop();
	};

	self.hover = function (elem) {
		var src = self.get_src(elem);
		var over = self.replace_over(src);
		return elem.src ? self.add_src_over(elem, src, over) : self.add_bg_over(elem, src, over);
	};

	self.replace_over = function (src) {
		return src.replace(/(?:_o)?(\.\w+)$/, '_o$1');
	};

	self.observe = $
		? function (target, type, listener) {
			$(target).bind(type + '.' + name_space, listener);
		} : window.addEventListener
			? function(target, type, listener) {
				target.addEventListener(type, listener, false);
			} : function(target, type, listener) {
				target.attachEvent('on' + type, function() {
					listener && listener.call(target, window.event);
				});
			};

	self.add_src_over = function (elem, src, over) {
		var img = new Image();
		img.src = over;
		self.observe(elem, 'mouseover', function () { elem.src = over; });
		self.observe(elem, 'mouseout', function () { elem.src = src; });
	};

	self.add_bg_over = function (elem, src, over) {
		var img = new Image();
		img.src = over;
		self.observe(elem, 'mouseover', function () {
			elem.style.backgroundImage = 'url(' + over + ')';
		});
		self.observe(elem, 'mouseout', function () {
			elem.style.backgroundImage = 'url(' + src + ')';
		});
	};

	self.exec_hover = function () {
		self.observe(window, 'load', function () {
			_hover(self.get_elems(self.overClass));
			function _hover (elems) {
				for (var i = 0, l = elems.length; i < l; self.hover(elems[i++]));
			}
		});
	};

	if (!/^Mozilla\/4\.0 \(compatible; MSIE (?:5\.5|6\.|7\.)/.test(navigator.userAgent)) {
		if (!self.noRoll) self.exec_hover();
		return;
	}

//-----------------------------------
// for old IE only
//-----------------------------------

	self.blank = 'images/blank.gif';
	self.eid = '_' + name_space + '_src';

	self.store = function (elem, val) {
		return val ? elem[self.eid] = val : elem[self.eid];
	};

	self.hover = function (elem) {
		var src = elem[self.eid] || (elem[self.eid] = self.get_src(elem));
		var over = self.replace_over(src);
		return elem.src ? self.add_src_over(elem, src, over) : self.add_bg_over(elem, src, over);
	};

	self.set_width = function (elem) {
		var cur = elem.currentStyle;
		if (cur.width != 'auto' || cur.height != 'auto') return;
		elem.style.width = elem.offsetWidth + 'px';
	};

	self.fix = function (elem) {
		elem.runtimeStyle.behavior = 'none';
		var src = elem[self.eid] || (elem[self.eid] = self.get_src(elem));
		if (!src) src = elem.src;
		if (!src) return;
		if (!/\.png$/.test(src.toLowerCase())) return;
		self.set_width(elem);
		if (elem.src) elem.src = self.blank;
		if (!elem.style.zoom && elem.style.zoom != '0') elem.style.zoom = 1;
		self.swap(elem, src);
		if (!elem.src) self.fix_bg_elem(elem);
		self.observe(elem, 'propertychange', function (env) {
			switch (env.propertyName) {
				case 'src':
					if (!elem.src || elem.src == self.blank) return;
					self.swap(elem, elem.src);
					elem[self.eid] = elem.src;
					elem.src = self.blank
				break;
				case 'style.backgroundImage':
					var src = self.get_src(elem);
					if (!src) return;
					self.swap(elem, src);
					elem.style.backgroundImage = 'none';
					elem[self.eid] = src;
				break;
			};
		});
	};

	self.fix_bg_elem = function (elem) {
		elem.style.backgroundImage = 'none';
		self.set_pos(elem);
		(elem.tagName.toUpperCase() == 'A') && (elem.style.cursor = elem.style.cursor || 'pointer');
	};

	self.set_pos = function (elem) {
		var tags = ['input', 'textarea', 'select'];
		var set = function (nodes, cursor) {
			for (var i = 0, n = nodes.length; i < n; ++i) {
				var node = nodes[i];
				var style = node.style;
				!style.position && (style.position = 'relative');
				if (!cursor) continue;
				!style.cursor && (style.cursor = cursor);
			}
		};
		while (tags.length) set(elem.getElementsByTagName(tags.pop()));
		set(elem.getElementsByTagName('a'), 'pointer');
	};

	self.swap = function (elem, src) {
		if (src == self.blank) return;
		var sizing = (elem.currentStyle.backgroundRepeat == 'no-repeat') ? 'crop' : 'scale';
		var al = 'DXImageTransform.Microsoft.AlphaImageLoader';
		if (elem.filters.length && al in elem.filters) {
			elem.filters[al].enabled = 1;
			elem.filters[al].src = src;
			return;
		}
		elem.style.filter = 'progid:' + al + '(src="' + src + '",sizingMethod="' + sizing + '");';
	};

	self.exec_pngfix = function () {
		var exp = 'expression(' + name_space + '.fix(this));';
		var div = $d.createElement('div');
		div.innerHTML = ([
			'div<div><style type="text/css">',
				'img, input { behavior : ' + exp + ' };',
				'.bgpng { behavior : ' + exp + ' };',
			'</style></div>'
		]).join('');
		$d.getElementsByTagName('head')[0].appendChild(div.getElementsByTagName('style')[0]);
	};

	if (!self.noRoll) self.exec_hover();
	if (!self.noFix) self.exec_pngfix();
};

