var unique_row_id = 0;

function cloneRow(e,keep,limit) {
	var par = null;
	if((par = e.getPrevious('.clone_parent')) == null) {
		if((par = e.getParent().getPrevious('.clone_parent')) == null) {
			keep = 'none';
			if((par = e.getPrevious('.clone_template')) == null)
				par = e.getParent().getPrevious('.clone_template');
		}
	}
	var row_id = par.get('row_id').toInt()+1;
	if(limit > 0) {
		if(row_id >= limit - 1)
			e.set('disabled','yes');
		else if(row_id > limit)
			return false;
	}
	var el = null;
	if(keep == 'last')
		el = par.clone().set('row_id',row_id);
	if(keep == 'defaults') {
		dbug.log('defaults');
		var temp = null;
		if((temp = par.getPrevious('.clone_default')) != null)
			if((temp = temp.getFirst()) != null)
				el = temp.clone().set('row_id',row_id);
	}
	if(el == null) {
		var temp = null;
		if((temp = par.getPrevious('.clone_template')) == null)
			temp = par;
		el = temp.clone().set('row_id',row_id).set('class','clone_parent').erase('id');
	}
	el.inject(par,'after');
	if(window.initializeRow)
		initializeRow(el);
	el = el.getNext('.clone_parent');
	while(el != null) {
		el.set('row_id',el.get('row_id').toInt()+1);
		
		el = el.getNext();
	}
	return row_id;
}

window.addEvent('domready',function() {
	$$('.clone_parent').each(function(e){
		if(window.initializeRow)
			initializeRow(e);
	});

	$$('.component_wrapper').each(function(e){
		if(e.innerHTML == '')
			e.setStyle('display','none');
	})
});

function executeFns(defaultFn,addFn,requireAdd,addFirst) {
	if(!(($type(defaultFn) == 'string' || $type(defaultFn) == 'function') &&
	   ($type(addFn) == 'string' || $type(addFn) == 'function'))) return false;
	if($type(requireAdd) != 'boolean') requireAdd = false;
	if($type(addFirst) != 'boolean') addFirst = false;
	if(requireAdd) {
		if(eval(addFn))
			eval(defaultFn);
	} else if(addFirst) {
		eval(addFn);
		eval(defaultFn);
	} else {
		eval(defaultFn);
		eval(addFn);
	}
}

function numRows(clone) {
	return clone.getChildren('.clone_parent').length;
}

Element.prototype.numRows = function(){
	return numRows(this);
};

function moveRow(e,where) {
	var par = e.getParent('.clone_parent');
	var swap = null;
	var row_id = par.get('row_id').toInt();
	switch(where) {
		case 'up':
			swap = par.getPrevious('.clone_parent');
			where = 'before';
			break;
		case 'down':
			swap = par.getNext('.clone_parent');
			where = 'after';
			break;
	}
	if(swap != null) {
		par.set('row_id',swap.get('row_id'));
		swap.set('row_id',row_id);
		par.inject(swap,where);
	}
}

function deleteRow(e,min) {
	var count = numRows(e.getParent('.clone_container'));
	if(count > min) {
		var par = e.getParent('.clone_parent');
		var row_id = parseInt(par.get('row_id'))-1;
		var el = par.getNext('.clone_parent');
		while(el != null) {
			row_id++;
			el.set('row_id',el.get('row_id').toInt()-1);
			el = el.getNext('.clone_parent');
		}
		par.getParent('.clone_container').getElement('.clone_add_btn').removeProperty('disabled');
		par.dispose();
		return row_id;
	}
	return count;
}

function insertRowIDs(e) {
	if($type(e) == 'event')
		e = e.target;
	$(e).getElements('.clone_parent input,.clone_parent textarea,.clone_parent select').each(recurseRowIDs);
	$(e).getElements('.dyn_sel_value_code_wrap').each(removeNames);
}

function getObjectClass(obj) {
    if (obj && obj.constructor && obj.constructor.toString) {
        var arr = obj.constructor.toString().match(
            /function\s*(\w+)/);

        if (arr && arr.length == 2) {
            return arr[1];
        }
    }

    return undefined;
}

function recurseRowIDs(e) {
	var name = '';
	if(e.getParent('.clone_template') == null && (name = e.get('name_template')) != null) {
		name = name.split('#');
		var par = null;
		if(name.length > 1 && (par = e.getParent('.clone_parent')) != null) {
			var i = name.length-1;
			var name_rows = name[i--];
			while(i >= 0 && (par = par.getParent('.clone_parent')) != null){
				name_rows = name[i--]+par.get('row_id')+name_rows;
			}
			e.set('name',name_rows);
		} else {
			e.set('name',name);
		}
	}
}

function removeNames(e) {
	if(e.getParent('.clone_template') != null || e.getStyle('display') == 'none') {
		e.getElements('input, select, textarea').each(function(elem) {elem.erase('name');});
	} else {
		e.getElements('input, select, textarea').each(function(elem) {elem.set('name',elem.get('name_template'));});
	}
}

function switchVisibleCodeBlock(e) {
	var par = e.getParent('.dyn_sel'); 
	var value = e.value;
	var id = par.get('id');
	par.getElement('.dyn_sel_code_container').getChildren('.dyn_sel_value_code_wrap').each(function(elem){
		if(!elem.hasClass('value:'+value))
			elem.setStyle('display','none');
		else
			elem.setStyle('display','');
	});
}

/*
 * @param element is a DOM element
 * @param levels is an integer denoting the number of DOM levels to move up from element
 * @return the element returned by performing the getParent() function on element levels times 
 */
function moveUpDOM(element, levels){
	var ret = element;
	for(var i = 0; i < levels; i++){
		if(ret.getParent() == null)
			return ret;
		ret = ret.getParent();
	}
	return ret;
}

//allows use of moveUpDOM(element, levels) in method form (element.moveUpDOM(levels))
Element.prototype.moveUpDOM = function(levels){
	return moveUpDOM(this, levels);
};

function reverseString(string){
	splittext = string.split('');
	revertext = splittext.reverse();
	reversed = revertext.join('');
	return reversed;
}

String.prototype.reverse = function(){
	return reverseString(this);
}

/*
 * @param form is a html <form> element
 * @return a JSON comprised of the inputs of form and their respective values; {input1name:input1value, ...} 
 */
function formToJSON(form){
	var json = {};
    form.getElements('input, select, textarea', true).each(function(el){
        if ((!el.name && !el.get('name_template')) || (el.isHidden() && !(el.hasClass('styled') && (el.type == 'checkbox' || el.type == 'radio')) && !el.hasClass('nothidden') && el.type != 'hidden') || el.disabled || el.type == 'submit' || el.type == 'reset' || el.type == 'file') return;
        var value = (el.tagName.toLowerCase() == 'select') ? Element.getSelected(el).map(function(opt){
            return opt.value;
        }) : ((el.type == 'radio' || el.type == 'checkbox') && !el.checked) ? null : el.value;
        $splat(value).each(function(val){
            if (typeof val != 'undefined') {
				if(el.get('name_template') != null)
	                json[el.get('name_template')] = val;
				else
					json[el.name] = val;
            }
        });
    });
    return json;
}

Element.implement({
  isHidden: function(){
    var w = this.offsetWidth, h = this.offsetHeight,
    force = (this.tagName === 'TR');
    return (w===0 && h===0 && !force) ? true : (w!==0 && h!==0 && !force) ? false : this.getStyle('display') === 'none';
  },

  isVisible: function(){
    return !this.isHidden();
  }
});

function detectBrowser() {
	if(Browser.ie5) $(document.body).addClass('ie5');
	else if(Browser.ie6) $(document.body).addClass('ie6');
	else if(Browser.ie7) $(document.body).addClass('ie7');
	else if(Browser.ie8) $(document.body).addClass('ie8');
	else if(Browser.ie && Browser.version > 8) $(document.body).addClass('ie9');
	else if(Browser.safari || Browser.chrome) $(document.body).addClass('webkit');
	else if(Browser.opera) $(document.body).addClass('opera');
	else if(Browser.firefox && Browser.version < 4) $(document.body).addClass('firefox');
	else if(Browser.firefox && Browser.version >= 4) $(document.body).addClass('firefox4');
	if(Browser.Platform.mac || Browser.safari) $(document.body).addClass('mac');
}

Form.Validator.addAllThese([
	['validate-time-24hr', {
		errorMsg: 'Please enter a valid time in 24-hour format (i.e. 23:45:12).',
		test: function(elem) {
			var regex = /^([0]?[0-9]|1[0-9]|2[0-4]):[0-5][0-9](:[0-5][0-9])?$/;
			return regex.test(elem.value);
		}
	}],
	['validate-timestamp', {
		errorMsg: 'Please enter a valid timestamp (i.e. 23:45).',
		test: function(elem) {
			var regex = /^([0-9]+:[0-5][0-9])?$/;
			return regex.test(elem.value);
		}
	}],
	['validate-img-crop', {
		errorMsg: 'You must crop or remove this image.',
		test: function(elem) {
			return (elem.get('cropped') == 'yes');
		}
	}],
	['minValue', {
		errorMsg: function(element,props) { 
			return 'You must enter a value greater than '+props.minValue+'.'; 
		},
		test: function(element,props) {
			return Form.Validator.getValidator('validate-numeric').test(element) && Number(element.value) >= Number(props.minValue);
		}
	}],
	['maxValue', {
		errorMsg: function(element,props) { 
			return 'You must enter a value less than '+props.minValue+'.'; 
		},
		test: function(element,props) {
			return Form.Validator.getValidator('validate-numeric').test(element) && Number(element.value) <= Number(props.minValue);
		}
	}],
	['validate-numeric-positive', {
		errorMsg: 'You must enter a positive number.',
		test: function(element) {
			return Form.Validator.getValidator('validate-numeric').test(element) && Number(element.value) >= 0;
		}
	}],
	['validate-numeric-negative', {
		errorMsg: 'You must enter a negative number.',
		test: function(element) {
			return Form.Validator.getValidator('validate-numeric').test(element) && Number(element.value) <= 0;
		}
	}],
	['validate-integer-positive', {
		errorMsg: 'You must enter a positive integer.',
		test: function(element) {
			return Form.Validator.getValidator('validate-integer').test(element) && Number(element.value) >= 0;
		}
	}],
	['validate-integer-negative', {
		errorMsg: 'You must enter a negative integer.',
		test: function(element) {
			return Form.Validator.getValidator('validate-integer').test(element) && Number(element.value) <= 0;
		}
	}]
]);

function disruption() {
	var disrupt = '<span style="display:none;">ijef</span>';
	$$('span[roofie="surprise"]').each(
		function(el) {
			el.set('html',el.get('bob')+disrupt+"@"+el.get('html'));
			el.addEvent('mouseover',
				function() {
					new Element('a', {
						'href':'m'+'ai'+'lto'+':'+el.get('html').replace(disrupt,"").split("").reverse().join(""),
						'class':'linked'
					}).wraps(el);
				});
			el.addEvent('mouseout',
				function() {
					var par = el.getParent();
					el.inject(par,'before');
					par.dispose();
				});
		});
}

function escapeHTML(unsafe) {
  return unsafe
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
}

function dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;

	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";

	if(typeof(arr) == 'object') { //Array/Hashes/Objects
		for(var item in arr) {
			var value = arr[item];

			if(typeof(value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "' ...\n";
				dumped_text += dump(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}
