/* -------------------------------------------------------------------------- */
/** 
 *    @fileoverview
 *       Image Swap / Rollover Control
 *
 *    @version rev012.2007-07-26
 *    @requires common.js
 */
/* -------------------------------------------------------------------------- */


var BA_ROLLOVER_AS_INSTANCES = [];



/* -------------------- Settings for BARolloverAutoSetup -------------------- */

var BA_ROLLOVER_AS_ENABLED  = true;
var BA_ROLLOVER_AS_SETTINGS = {
	'rollover' : {
		findAtOnce : false,
		targets    : ['a', 'input'],  // this will be ignored when 'findAtOnce' is false.
		exclude    : 'norollover',
		statusSet  : {
			'normal' : '',
			'hover'  : '_o'
		},
		handlers   : {
			'mouseover' : function(node) { this.setStatus('hover'  ); },
			'mouseout'  : function(node) { this.setStatus('default'); }
		}
	}
};



/* -------------------- Constructor : BARollover -------------------- */

function BARollover(node, statusSet, excludeCName) {
	this.node         = node;
	this.statusSet    = statusSet;
	this.status       = 'default';
	this.cNamePrefix  = 'pseudo-';
	this.excludeCName = excludeCName;
	this.images       = [];
	
	if (BA.env.isDOMReady) {
		this.init();
	}
}

BARollover.prototype = {
	init : function () {
		if (this.nodeValidate(this.node)) {
			var roi = new BARolloverImage(this.node, this.statusSet);
			this.images.push(roi);
		} else {
			var nodes = BAConcatNodeList(this.node.getElementsByTagNameBA('img'), this.node.getElementsByTagNameBA('input'));
			nodes.forEach(function(node) {
				if (this.nodeValidate(node)) {
					var roi = new BARolloverImage(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.getAttributeBA('type').match(/^image$/i)) {
			return false
		} else if (this.excludeCName && node.hasClassNameBA(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() {
		this.status = status;
		this.images.forEach(function(image) {
			image.setStatus(status);
		});
		for (var i in this.statusSet) {
			this.node.removeClassNameBA(this.cNamePrefix + i);
		}
		if (this.statusSet[status]) {
			this.node.appendClassNameBA(this.cNamePrefix + status);
		}
	},

	setStatus : function(status) {
		this.status = status;
		this.images.forEach(function(image) {
			image.setStatus(status);
		});
		for (var i in this.statusSet) {
			this.node.removeClassNameBA(this.cNamePrefix + i);
		}
		if (this.statusSet[status]) {
			this.node.appendClassNameBA(this.cNamePrefix + status);
		}
	}
}



/* -------------------- Constructor : BARolloverImage -------------------- */

function BARolloverImage(node, statusSet) {
	this.node          = node;
	this.statusSet     = statusSet;
	this.status        = '';
	this.defaultStatus = '';
	this.images        = {};

	if (BA.env.isDOMReady) {
		this.init();
	}
}

BARolloverImage.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.getAttributeBA('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] = BAPreloadImage(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.setAttributeBA('src', this.images[status].src);
//			}
		}
	}
}



/* -------------------- Constructor : BARolloverAutoSetupByClassName -------------------- */

function BARolloverAutoSetupByClassName(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 (BA.env.isDOMReady) {
		this.init();
	}
}

BARolloverAutoSetupByClassName.prototype = {
	init : function() {
		if (this.findAtOnce) {
			this.initNodes_atOnce();
		} else {
			this.initNodes_sequential();
		}
	},
	
	initNodes_atOnce : function() {
		this.targetEName.forEach(function(nodeName) {
			this.baseNode.getElementsByClassNameBA(this.targetCName, nodeName).forEach(function(node) {
				this.initNode(node);
			}, this);
		}, this);
	},
	
	initNodes_sequential : function() {
		document.addEventListenerBA('mouseover', function(e) {
			var tname = this.targetCName;
			var tnode = (function(node) {
				BARegisterDOMMethodsTo(node);
				return (node.instanceOf == 'BAElement' && node.hasClassNameBA && node.hasClassNameBA(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.__BARolloverAutoSetup_instanceID__ != 'number') {
			node.__BARolloverAutoSetup_instanceID__ = BA_ROLLOVER_AS_INSTANCES.length;
			var RO = new BARollover(node, this.statusSet, this.excludeCName);
			BA_ROLLOVER_AS_INSTANCES.push(RO);
			for (var eventType in this.handlers) {
				node.addEventListenerBA(eventType, this.doCallBack, this);
			}
		}
	},

	doCallBack : function(e) {
		var type = e.type;
		var node = e.currentTarget;
		var id   = node.__BARolloverAutoSetup_instanceID__;
		if (this.handlers[type]) {
			this.handlers[type].call(BA_ROLLOVER_AS_INSTANCES[id], node);
		}
	}
}







/* -------------------- Function : BARolloverAutoSetup -------------------- */

function BARolloverAutoSetup() {
	if (BA_ROLLOVER_AS_ENABLED && !BAAlreadyApplied(arguments.callee)) {
		for (var className in BA_ROLLOVER_AS_SETTINGS) {
			new BARolloverAutoSetupByClassName(className, BA_ROLLOVER_AS_SETTINGS[className]);
		}
	}
}







/* -------------------- Main : register start-up -------------------- */

if (typeof BA == 'object' && BA.ua.isDOMReady) {
	BAAddOnload(BARolloverAutoSetup);
}
