﻿/*
 * hider.js
 * ---
 * EZEL 2010/11
 * ---
 * requires:
 *   jquery.js
 * ---
 */

/*jslint browser: true */
/*global window: false, $: false, ESSENCE: true, alert: false */
/**/

if (typeof ESSENCE === 'undefined') { 
	ESSENCE = {}; 
}
ESSENCE.Hider = (function () {
    'use strict';
    var MAIN, CONST, INNER;

	CONST = {
		selMaster: '.HiderMaster',
		selSlave: '.Hider',
		clsHidden: 'hidden',
		attrVisible: 'hider:visible'
	};
	
	INNER = {
		masters: []
	};

	function forall_p(arr, fnc) {
		var i, tmp;
		for (i = 0; i < arr.length; i++) {
			tmp = fnc(arr[i]);
			if (typeof tmp !== 'undefined' && tmp === false) {
				break;
			}
		}
	}

	function newSlave(el) {
		var that = {
			qel: null,
			visible: [],
			isValueVisible: function (value) {
				var result = false;
				forall_p(this.visible, function (vis) {
					if (value === vis) {
						result = true;
						return false;
					}
				});
				return result;
			},
			update: function (value) {
				if (this.isValueVisible(value)) {
					this.qel.removeClass(CONST.clsHidden);
				} else {
					this.qel.addClass(CONST.clsHidden);
				}
			},
			getParams: function () {
				return this.qel.attr(CONST.attrVisible);
			},
			init: function (el) {
				this.qel = $(el);
				var params = this.getParams();
				if ((typeof params === 'string') && (params.length > 0)) {
					this.visible = params.split(',');
				}
			}
		};
		that.init(el);
		return that;
	}

	function newMaster(el) {
		var that = {
			qmaster: null,
			hidden: [],
			update: function (evt) {
				var val = this.qmaster.val();
				forall_p(this.hidden, function (slv) {
					slv.update(val);
				});
			},
			addSlave: function (el) {
				var slv = newSlave($(el));
				this.hidden.push(slv);
			},
			init: function (qmaster) {
				var mstr = this, qslaves, qpar = qmaster.parent();
				mstr.qmaster = qmaster;
				while (qpar && qpar.length > 0) {
					qslaves = qpar.find(CONST.selSlave);
					if (qslaves.length > 0) {
						break;
					}
					qpar = qpar.parent();
				}
				forall_p(qslaves, function (el) {
					mstr.addSlave(el);
				});
				mstr.qmaster.bind('change', function () { mstr.update(); });
				mstr.update();
			}
		};
		that.init($(el));
		return that;
	}

	function addMaster(el) {
		var mstr = newMaster(el);
		INNER.masters.push(mstr);
	}

	function initHiders(selParent) {
		if (typeof selParent === 'undefined') {
			selParent = document;
		}
		$(CONST.selMaster, $(selParent)).each(function () {
			addMaster(this);
		});
	}

	$(function () { 
		initHiders();
	});
	
	MAIN = {
		init: initHiders,
		isHidden: function (qel) {
			return qel.hasClass(CONST.clsHidden);
		}
	};
	
	return MAIN;
} ());

