/* -------------------------------------------------------------------------- */
/** 
 *    @fileoverview
 *       Image Swap / Rollover Control
 *
 *    @version rev001 2009/08/26
 *    @requires common.js
 */
/* -------------------------------------------------------------------------- */


var CWJ_ROLLOVER_AS_INSTANCES = [];



/* -------------------- Settings for CWJRolloverAutoSetup -------------------- */

var CWJ_ROLLOVER_AS_ENABLED  = true;
var CWJ_ROLLOVER_AS_SETTINGS = {
	'rollover' : {
		findAtOnce : false,
		targets    : ['a', 'input'],  // this will be ignored when 'findAtOnce' is false.
		exclude    : 'norollover',
		statusSet  : {
			'normal' : '',
			'stay'   : '_s',
			'hover'  : '_o'
		},
		handlers   : {
			'mouseover' : function(node) { this.setStatus('hover'  ); },
			'mouseout'  : function(node) { this.setStatus('default'); }
		}
	}
};



/* -------------------- Constructor : CWJRollover -------------------- */

function CWJRollover(node, statusSet, excludeCName) {
	this.node         = node;
	this.statusSet    = statusSet;
	this.status       = 'default';
	this.cNamePrefix  = 'pseudo-';
	this.excludeCName = excludeCName;
	this.images       = [];
	
	if (CWJ.env.isDOMReady) {
		this.init();
	}
}

CWJRollover.prototype = {
	init : function () {
		if (this.nodeValidate(this.node)) {
			var roi = new CWJRolloverImage(this.node, this.statusSet);
			this.images.push(roi);
		} else {
			var nodes = CWJConcatNodeList(this.node.getElementsByTagNameCWJ('img'), this.node.getElementsByTagNameCWJ('input'));
			nodes.forEach(function(node) {
				if (this.nodeValidate(node)) {
					var roi = new CWJRolloverImage(node, this.statusSet);
					this.images.push(roi);
				}
			}, this);
		}
		return this;
	},

	nodeValidate : function(node) {
		if (!node || !node.nodeName) {
			return false;
		} else if (!node.nodeName.match(/^(img|input)$/i)) {
			return false
		} else if (node.nodeName.match(/^input$/i) && !node.getAttributeCWJ('type').match(/^image$/i)) {
			return false
		} else if (this.excludeCName && node.hasClassNameCWJ(this.excludeCName)) {
			return false
		} else {
			return true;
		}
	},

	getDefaultStatus : function() {
		var stArr  = this.images.map(function(image) { return image.getDefaultStatus() });
		var status = stArr[0] || '';
		var mixed  = stArr.some(function(st) { return st != status });
		return (mixed) ? '' : status;
	},

	getStatus : function() {
		return this.status;
	},

	setStatus : function(status) {
		this.images.forEach(function(image) {
			image.setStatus(status);
		});
//		this.node.removeClassNameCWJ(this.cNamePrefix + this.status);
//		if (this.statusSet[status]) {
//			this.node.appendClassNameCWJ(this.cNamePrefix + status);
//		}
		this.status = status;
	}
}



/* -------------------- Constructor : CWJRolloverImage -------------------- */

function CWJRolloverImage(node, statusSet) {
	this.node          = node;
	this.statusSet     = statusSet;
	this.status        = '';
	this.defaultStatus = '';
	this.images        = {};

	if (CWJ.env.isDOMReady) {
		this.init();
	}
}

CWJRolloverImage.prototype = {
	init : function () {
		var arr = [];
		for (var i in this.statusSet) {
			arr.push(this.statusSet[i]);
		}
		var statusPtn = new RegExp('(' + arr.join('|') + ')$');
		var suffixPtn = /\.(jpe?g|gif|png)$/i;

		var src    = this.node.getAttributeCWJ('src');
		var suffix = (suffixPtn.test(src )) ? src.match (suffixPtn)[0] : '';
		var name   = src.replace (suffixPtn, '');
		var status = (statusPtn.test(name)) ? name.match(statusPtn)[0] : '';
		var remain = name.replace(statusPtn, '');
		if (suffix && remain) {
			for (var i in this.statusSet) {
				this.images[i] = CWJPreloadImage(remain + this.statusSet[i] + suffix);
				if (this.statusSet[i] == status) {
					this.defaultStatus = this.status = i;
				}
			}
		}
	},
	
	getStatus : function () {
		return this.status;
	},

	getDefaultStatus : function () {
		return this.defaultStatus;
	},

	setStatus : function (status) {
		if (status == 'default') {
			status = this.defaultStatus;
		}
		if (this.images[status]) {
			this.status = status;
//			if (this.images[status].complete) {
				this.node.setAttributeCWJ('src', this.images[status].src);
				this.setStatus_AILoader(this.images[status].src);  // for WinIE5.5/6.x
//			}
		}
	},
	
	setStatus_AILoader : function(src) {
		if (this.node.__CWJAILoaderProcessed__ && src && src.substr(src.length - 4).toLowerCase() == '.png') {
			var span = this.node.nextSibling;
			span.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '", sizingMethod="scale")';
		}
	}
}






/* -------------------- Constructor : CWJRolloverAutoSetupByClassName -------------------- */

function CWJRolloverAutoSetupByClassName(className, settingData) {
	if (!className || !settingData) return;
	
	this.baseNode     = document;
	this.targetCName  = className;
	this.findAtOnce   = settingData.findAtOnce;
	this.targetEName  = settingData.targets || ['*'];
	this.excludeCName = settingData.exclude;
	this.statusSet    = settingData.statusSet;
	this.handlers     = settingData.handlers;
	
	if (CWJ.env.isDOMReady) {
		this.init();
	}
}

CWJRolloverAutoSetupByClassName.prototype = {
	init : function() {
		if (this.findAtOnce) {
			this.initNodes_atOnce();
		} else {
			this.initNodes_sequential();
		}
	},
	
	initNodes_atOnce : function() {
		this.targetEName.forEach(function(nodeName) {
			this.baseNode.getElementsByClassNameCWJ(this.targetCName, nodeName).forEach(function(node) {
				this.initNode(node);
			}, this);
		}, this);
	},
	
	initNodes_sequential : function() {
		document.addEventListenerCWJ('mouseover', function(e) {
			var tname = this.targetCName;
			var tnode = (function(node) {
				CWJRegisterDOMMethodsTo(node);
				return (node.instanceOf == 'CWJElement' && node.hasClassNameCWJ && node.hasClassNameCWJ(tname)) ?
					node : (node.parentNode) ?
						arguments.callee(node.parentNode) : null;
			})(e.target);
			if (tnode) {
				this.initNode(tnode);
				var _e = {};
				for (var prop in e) {
					_e[prop] = e[prop];
				}
				_e.type = 'mouseover';
				_e.currentTarget = tnode;
				this.doCallBack(_e);
			}
		}, this);
	},

	initNode : function(node) {
		if (typeof node.__CWJRolloverAutoSetup_instanceID__ != 'number') {
			node.__CWJRolloverAutoSetup_instanceID__ = CWJ_ROLLOVER_AS_INSTANCES.length;
			var RO = new CWJRollover(node, this.statusSet, this.excludeCName);
			CWJ_ROLLOVER_AS_INSTANCES.push(RO);
			for (var eventType in this.handlers) {
				node.addEventListenerCWJ(eventType, this.doCallBack, this);
			}
		}
	},

	doCallBack : function(e) {
		var type    = e.type;
		var node    = e.currentTarget;
		var related = e.relatedTarget;
		var flag    = true;
		if (e.relatedTarget) {
			flag = (function(_node) {
				return (!_node)         ? true  :
				       ( _node == node) ? false :
				                         arguments.callee(_node.parentNode);
			})(e.relatedTarget);
		}
		if (flag && this.handlers[type]) {
			var id = node.__CWJRolloverAutoSetup_instanceID__;
			this.handlers[type].call(CWJ_ROLLOVER_AS_INSTANCES[id], node);
		}
	}
}







/* -------------------- Function : CWJRolloverAutoSetup -------------------- */

function CWJRolloverAutoSetup() {
	if (CWJ_ROLLOVER_AS_ENABLED && !CWJAlreadyApplied(arguments.callee)) {
		for (var className in CWJ_ROLLOVER_AS_SETTINGS) {
			new CWJRolloverAutoSetupByClassName(className, CWJ_ROLLOVER_AS_SETTINGS[className]);
		}
	}
}







/* -------------------- Main : register start-up -------------------- */

if (typeof CWJ == 'object' && CWJ.ua.isDOMReady) {
	CWJAddOnload(CWJRolloverAutoSetup);
}
