/**
 * jQuery Conditions 1.0.0
 *
 * Copyright 2016 Bejamin Rojas
 * @license Released under the MIT license.
 * http://jquery.org/license
 */
(function($) {
	"use strict";

	$.fn.conditions = function(conditions) {
		return this.each( function(index, element) {
			var CJS = new ConditionsJS(element, conditions, $.fn.conditions.defaults);
			CJS.init();
		});
	};

	$.fn.conditions.defaults = {
		condition:	null,
		actions:	{},
		effect:		'fade'
	};

	var ConditionsJS = function(element, conditions, defaults) {
		var that = this;

		that.element	= $(element);
		that.defaults	= defaults;
		that.conditions	= conditions;
		that._init		= false;

		if(!$.isArray(that.conditions)) {
			that.conditions = [that.conditions];
		}

		$.each(that.conditions, function(i, v) {

			v = $.extend({}, that.defaults, v);

			that.conditions[i] = v;

		});

	};

	ConditionsJS.prototype.init = function() {
		var that = this;
		that._init = true;
		// Set up event listener
		$(that.element).on('change', function() {
			that.matchConditions();
		});

		$(that.element).on('keyup', function() {
			that.matchConditions();
		});

		//Show based on current value on page load
		that.matchConditions(true);
	};

	ConditionsJS.prototype.matchConditions = function(init) {
		var that = this;

		if(!init) {
			that._init = false;
		}

		$.each(that.conditions, function(ind, cond) {

			var condition_matches = false, all_conditions_match = true;

			if(!$.isArray(cond.conditions)) {
				cond.conditions = [cond.conditions];
			}

			$.each(cond.conditions, function(i, c) {

				c.element = $(c.element);

				switch(c.type) {
					case 'value':
					case 'val':
						switch(c.operator) {
							case '===':
							case '==':
							case '=':
								condition_matches = c.element.val() === c.condition;
								break;
							case '!==':
							case '!=':
								condition_matches = c.element.val() !== c.condition;
								break;
							case 'array':
								condition_matches = $.inArray( c.element.val(), c.condition ) !== -1;
								break;
							case '!array':
								condition_matches = $.inArray( c.element.val(), c.condition ) === -1;
								break;
						}
						break;
					case 'checked':
						switch(c.operator) {
							case 'is':
								condition_matches = c.element.is(':checked');
								break;
							case '!is':
								condition_matches = !c.element.is(':checked');
								break;
						}
				}

				if(!condition_matches && all_conditions_match) {
					all_conditions_match = false;
				}

			});

			if(all_conditions_match) {

				if(!$.isEmptyObject(cond.actions.if)) {

					if(!$.isArray(cond.actions.if)) {
						cond.actions.if = [cond.actions.if];
					}

					$.each(cond.actions.if, function(i, condition) {
						that.showAndHide(condition, cond.effect);
					});

				}

			}
			else {

				if(!$.isEmptyObject(cond.actions.else)) {

					if(!$.isArray(cond.actions.else)) {
						cond.actions.else = [cond.actions.else];
					}

					$.each(cond.actions.else, function(i, condition) {
						that.showAndHide(condition, cond.effect);
					});

				}

			}

		});

	};

	ConditionsJS.prototype.showAndHide = function(condition, effect) {
		var that = this;

		switch(condition.action) {
			case 'show':
				that._show($(condition.element), effect);
				break;
			case 'hide':
				that._hide($(condition.element), effect);
				break;
		}

	};

	ConditionsJS.prototype._show = function(element, effect) {
		var that = this;

		if(that._init) {
			element.show();
		}
		else {
			switch(effect) {
				case 'appear':
					element.show();
					break;
				case 'slide':
					element.slideDown();
					break;
				case 'fade':
					element.fadeIn( 300 );
					break;
			}
		}

	};

	ConditionsJS.prototype._hide = function(element, effect) {
		var that = this;

		if(that._init) {
			element.hide();
		}
		else {
			switch(effect) {
				case 'appear':
					element.hide();
					break;
				case 'slide':
					element.slideUp();
					break;
				case 'fade':
					element.fadeOut( 300 );
					break;
			}
		}

	};

}(jQuery));