/**
  * Constructor
  *
  * @param String id Id of element to be replicated or removed
	* @param boolean noInitialization If this is true, no initialization is performed
  */
function HTMLReplicator(id) {
	this.elementId = id;
	this.htmlStack = [];
	this.insertBefore = null;
	this.order = 0; // order of the first ordered item in the block of HTML code
	this.formNumber = 0;
	if (arguments.length == 1 || arguments[1] != true)
		this.initialize();
}

/**
  * Analyzes the node in order to find parts which must be rewritten
	* during replication
	*
	* @return void
	*/
HTMLReplicator.prototype.initialize = function() {
	var element;

	element = document.getElementById(this.elementId);
	if (!element)
		alert('No element (id = "' + this.elementId + '") found!');
	else
		this.htmlStack.push(element);
	this.parent = element.parentNode;
	for (i = this.parent.childNodes.length - 1; i > 0; i--)
		if (this.parent.childNodes.item(i - 1) == element) {
			this.insertBefore = this.parent.childNodes.item(i);
			break;
		}
	this.analyze(element);
}

/**
  * Correct parts of code which are not the same for replicated portions of code
	*/
HTMLReplicator.prototype.doReplacements = function(node) {
	var i, reg, matches, newNumber, newVal, keys, value;

	reg = /^(\d+)\.$/;
	if (node.nodeValue != undefined &&
			(matches = reg.exec(node.nodeValue)) != null)
		node.nodeValue =  (parseInt(this.order) + this.htmlStack.length - 1) + '.';

	if (node.getAttribute != undefined
			&& node.tagName == 'INPUT'
			&& node.type != 'checkbox'
			&& node.type != 'button'
			&& node.value != '')
		node.value = '';

	reg = /\[(\d+)\]/;
	keys = ['name', 'for', 'id'];
	for (i = 0; i < keys.length; i++)
		if (node.getAttribute != undefined &&
				(name = node.getAttribute(keys[i])) != undefined &&
				(matches = reg.exec(name)) != null) {
			newNumber = (parseInt(this.formNumber) + this.htmlStack.length) - 1;
			newVal = name.replace(reg, '[' + newNumber + ']');
			if(keys[i] == 'name' && node.type == 'radio')
				node.setAttribute('value', newNumber);
			else
				node.setAttribute(keys[i], newVal);
		}

	if (node.childNodes != undefined)
		for (i = 0; i < node.childNodes.length; i++)
			this.doReplacements(node.childNodes.item(i));
}

/**
  * Analyzes the html code to be replicated
	*
	* @param Node
	* @return void
	*/
HTMLReplicator.prototype.analyze = function(node) {
	var i, reg, matches, name;

	reg = /^(\d+)\.$/;
	if (node.nodeValue != undefined &&
			(matches = reg.exec(node.nodeValue)) != null)
		this.order = matches[1];

	reg = /\[(\d+)\]/;
	if (node.getAttribute != undefined &&
			(name = node.getAttribute('name')) != undefined &&
			(matches = reg.exec(name)) != null)
		this.formNumber = matches[1];

	if (node.childNodes != undefined)
		for (i = 0; i < node.childNodes.length; i++)
			this.analyze(node.childNodes.item(i));
}

/**
  * Adds a copy of html element behind the last one
	*
	* @param int count Number of copies to be added
	*/
HTMLReplicator.prototype.add = function(all) {
	var i, ii, length, node, name, count;
	if(all)
		count = (document.getElementById('count_file').value > 1) ? document.getElementById('count_file').value : 1;
	else
		count = 1;

	length = arguments.length ? arguments[0] : 1;
	for (ii = 0; ii < count; ii++) {
		for (i = 0; i < length; i++) {
			node = this.duplicateNode(this.htmlStack[0], this.parent,
				this.insertBefore)
			this.htmlStack.push(node);
			this.doReplacements(node);
		}
	}

}


/**
  * Returns true if the element may be removed
	*
	* @param Node node
	* @return boolean
	*/
HTMLReplicator.prototype.mayBeRemoved = function(node) {
	var i;

	if (node.tagName == 'INPUT' && node.type != 'checkbox' && node.value != '')
		return false;
	if (node.childNodes != undefined)
		for (i = 0; i < node.childNodes.length; i++)
			if (!this.mayBeRemoved(node.childNodes.item(i)))
				return false;
	return true;
}

/**
  * Removes the last item generated
	*
	* @return void
	*/
HTMLReplicator.prototype.remove = function() {
	var tag;

	if (this.htmlStack.length > 1 && this.mayBeRemoved(this.htmlStack[this.htmlStack.length - 1])) {
		tag = this.htmlStack.pop();
		tag.parentNode.removeChild(tag);
	}
}

/**
  * Makes a copy of node, which is added to parent
	*
	* @param Node node
	* @param Node parent
	* @param Node InsertBefore If this is defined, node is not appended at the
	*   end but inserted before the specified node
	* @return Node Returns the duplicated Node
	*/
HTMLReplicator.prototype.duplicateNode = function(node, parent) {
	var newNode, i;

	newNode = node.cloneNode(false);
	if (newNode.getAttribute != undefined &&
			newNode.getAttribute('id') == this.elementId)
		newNode.removeAttribute('id');

	for (i = 0; i < node.childNodes.length; i++)
		this.duplicateNode(node.childNodes[i], newNode);

	if (arguments.length >= 3 && arguments[2])
		parent.insertBefore(newNode, arguments[2]);
	else
		parent.appendChild(newNode);

	return newNode;
}

/**
  * Set implicit sort order of input elements
	*
	* @param Node node
	* @param Integer actualSortOrder
	* @return Integer Returns actualSortOrder
	*/
HTMLReplicator.prototype.sortAttachment = function() {

 		var actualSortOrder = 10;
 		var allInputs = document.getElementsByTagName('INPUT');
	    var limit = allInputs.length;
	    for(var i = 0; i < limit; i++){
	    	 if ((allInputs[i].type == 'text') && allInputs[i].name.match(/sorting/))
	         {
	             	allInputs[i].value = actualSortOrder;
	             	actualSortOrder += 10;
	         }
	    }

}

/**
 * Set implicit sort order of input elements
	*
	* @param Node node
	* @param Integer actualSortOrder
	* @return Integer Returns actualSortOrder
	*/
HTMLReplicator.prototype.sortMassEdit = function() {

		var actualSortOrder = 10;
		var allInputs = document.getElementsByTagName('INPUT');
	    var limit = allInputs.length;
	    for(var i = 0; i < limit; i++){
	    	 if ((allInputs[i].type == 'text') && allInputs[i].name.match(/sort_order/))
	         {
	             	allInputs[i].value = actualSortOrder;
	             	actualSortOrder += 10;
	         }
	    }

}
/**
  * This function check input with name 'allow_zoom'
	*
	* @param String value
	*/
HTMLReplicator.prototype.checkAll = function(value){

      var allInputs = document.getElementsByTagName('INPUT');
      var limit = allInputs.length;
      for(var i = 0; i < limit; i++)
      {
         if ((allInputs[i].type == 'checkbox') && allInputs[i].name.match(/allow_zoom/))
         {
             if (allInputs[i].name.indexOf(value) != -1)
             	allInputs[i].checked = true;
         }
      }
}
/**
  * This function uncheck input with name 'allow_zoom'
	*
	* @param String value
	*/
HTMLReplicator.prototype.uncheckAll = function(value){

      var allInputs = document.getElementsByTagName('INPUT');
      var limit = allInputs.length;
      for(var i = 0; i < limit; i++)
      {
         if ((allInputs[i].type == 'checkbox') && allInputs[i].name.match(/allow_zoom/))
         {
             if (allInputs[i].name.indexOf(value))
             	allInputs[i].checked = false;
         }
      }
}

