// JavaScript Document

(function($) {
	$.extend($.pform.prototype, {
		/**
		 * pform inicalizacio elott fut le, feladata: ha a html mar ugy generalodik le, hogy van tobb repetition blokk renderelve
		 * akkor azon blokkok alapjan kiegesziti a validator.blocks tombot
		 */
		beforeInitialization: function() {
			var newBlocks = [];
			for (var i in this.validator.blocks) {
				if (typeof(this.validator.blocks[i].options)=='undefined') continue; 
				if (this.validator.blocks[i].options.repeat==true) {
					var existings = this.getExistings(this.validator.blocks[i].block_id);
					if (existings>0) {
						this.validator.blocks[i].iterator = 0;
						for (var j=1; j<existings; j++) {
							var newBlock = $.extend(true, {}, this.validator.blocks[i]);
							newBlock.iterator = j;
							newBlocks.push(newBlock);
						}
					}
				}
			}
			if( this.validator.blocks ) {
				this.validator.blocks=this.validator.blocks.concat(newBlocks);
			}
		},
		/**
		 * pform inicalizacio utan fut le, a repetition blokkok inicializaciojat inditja el
		 */
		afterInitialization: function() {
			for (var i in this.validator.blocks) {
				if (this.validator.blocks[i].options.repeat==true) this.validator.blocks[i].initializeRepetition();
			}
		},
		/**
		 * megszamolja, hogy adott blokk tipusbol (block_id ugyanaz) hany peldany van mar klonozva
		 * @return {Integer}
		 */
		getExistings: function(block_id) {
			var $existingFieldsets = $('[id^='+block_id+']');
			return $existingFieldsets.length;
		}
	});
	$.extend($.block.prototype, {
		/**
		 * blokk repetition inicializalasa
		 * @return void
		 */
		initializeRepetition: function() {
			//console.time('initializeRepetition');
			var pform = this.$parentForm.data('pform');
			if (!this.block_id) {
				log('repetition eseteben kotelezo a block_id megadasa!', 3);
				return false;
			}
			if (typeof(this.iterator)=='undefined')	this.convertBlock(0);
			this.createPanel();
			
			var position = this.getPosition();
			this.convertBlock(position, false); 
			this.setPanel(position);
			//console.timeEnd('initializeRepetition');
		},
		/**
		 * adott blokkhoz tartozo fieldset elemet visszaadja
		 * @param {Object} $form
		 * @return {Object} $
		 */
		getFieldsetElement: function($form) {
			var $fieldsetElement;
			if(this.block_id) {
				$fieldsetElement = $('#'+this.block_id);
			}
			else {
				$fieldsetElement = $('fieldset', $form);
			}
			
			if (!$fieldsetElement.length) {
				var selector = "#"+this.block_id+":"+this.iterator;
				selector = selector.replace(":", "\\:");
				$fieldsetElement = $(selector)
			}
			return $fieldsetElement;
		},
		/**
		 * Azonos tipusu (block_id egyenlo) blokkok kozul hanyadik a DOM-ban jelen blokk $fieldsetElementje
		 * @return {Integer}
		 */
		getPosition: function() {
			//console.time('getPosition');
			var $prevFieldsetInstances = this.$fieldsetElement.prevAll('[id^='+this.block_id+']');
			//console.timeEnd('getPosition');
			return $prevFieldsetInstances.length;
		},
		/**
		 * Blokkhoz tartozo elemek konverzioja a megadott értéknek megfelelően, eseménykezelők rendbetétele
		 * @param {Integer} 
		 * @param {Boolean} - ujra inicializalja-e az idetartozo fieldeket (mindig kell, kiveve moveDown es moveUp utan)
		 * @return void
		 */
		convertBlock: function(position) {
			// ha mar jol van beallitva ez elem akkor nem konvertalunk, kiveve ha van radio elem (radio problem miatt)
			if (position == this.position && $('input:radio', this.$fieldsetElement).length==0 ) return;
			var needToReInit = false;
			var $els = $('*', this.$fieldsetElement); // csak az input, select, label, textarea elemeket kellene kivlasztani, de ie nem viszi a megoldast
			var repetitionIdSeparator = this.options.repetitionIdSeparator;
			this.position = position;
			var id = this.$fieldsetElement[0].id;
			if (id.lastIndexOf(repetitionIdSeparator) > 0) {
				id = id.substr(0, id.lastIndexOf(repetitionIdSeparator));
			}
			this.$fieldsetElement[0].id = id+repetitionIdSeparator+this.position;
			$.each($els, function() {
				$el = $(this);
				// id csere
				if ($el[0].id) {
					var id = $el[0].id;
					if (id.lastIndexOf(repetitionIdSeparator) > 0) {
						id = id.substr(0, id.lastIndexOf(repetitionIdSeparator));
					}
					$el[0].id = id+repetitionIdSeparator+position;	
				}
				// name csere
				if ($el[0].name) {
					var name = $el[0].name;
					if (/[\d]/.test(name)) {
						name = name.replace(/[\d]+/, position);
					}
					else if (/\[\]/.test(name)) {
						name = name.replace(/\[\]/, '['+position+'][]');
					}
					else {
						name = name+'['+position+']';
					}
					$el[0].name = name;
				}
				// for csere
				if ($el.attr('for')) {
					var htmlFor = $el.attr('for');
					if (htmlFor.lastIndexOf(repetitionIdSeparator) > 0) {
						htmlFor = htmlFor.substr(0, htmlFor.lastIndexOf(repetitionIdSeparator));
					}
					$el.attr('for', htmlFor+repetitionIdSeparator+position);	
				}
				// radio csere ie alaltt
				if ($.browser.msie && $.browser.version != "8.0") {
					if ( $el[0].type == "radio" ) {
						needToReInit = true;
						if ( $el.attr('checked')==true ) {
							var strChecked="checked='checked'";
						} 
						else {
							var strChecked="";
						}
						var newRadioEl = document.createElement('<input type="'+$el[0].type+'" id="'+id+':'+position+'" name="' + name + '" value="' + $el[0].value + '" '+strChecked+'>');
						var parentNode = $el[0].parentNode;
						parentNode.insertBefore(newRadioEl, $el[0]);
						parentNode.removeChild($el[0]);
						//$($el[0]).replaceWith(newRadioEl);
					}
				}
			});
			// ha ujonnan hozzaadott block, akkor az ala tartozo fieldeket ujra kell inicializalnunk
			if (this.isNewblock===true || needToReInit==true) {
				for (var i in this.fields) {
					this.fields[i].$elements = $('#'+this.fields[i].name+this.options.repetitionIdSeparator+this.position); //@TODO: momentan nem mukodik, escapeles lehet a gond : 
					if (this.fields[i].$elements.length==0) {
						var selector = '[name^=' + this.fields[i].name + '\\['+this.position+'\\]]';
						//var selector = '[name^=' + this.fields[i].name + '][name$=['+this.position+']]';
						this.fields[i].$elements = $(selector, this.$fieldsetElement);
					}
					this.fields[i].$elements.unbind();
					this.fields[i].setElements();
					this.fields[i].checkField();
				}
				this.isNewblock = false;
			}
			// csak debug
			//$('.debug', this.$fieldsetElement).remove();
			//this.$fieldsetElement.prepend("<span class='debug'>"+this.position+"</span>");
		},
		/**
		 * Egy blokkban ki-be kapcsolja a repetition gombokat a pozicionak es a configoknak megfeleloen
		 */
		setPanel: function(position) {
			var pform = this.$parentForm.data('pform');
			var instances = pform.getExistings(this.block_id);
			// mozgatas felfele gomb
			if (position==0) {
				this.$moveUpButton.addClass(this.options.repetitionPanelDisabledClass);	
				if ($.browser.msie && $.browser.version == "6.0" ) this.$moveUpButton.addClass('up_'+this.options.repetitionPanelDisabledClass);
			}
			else {
				this.$moveUpButton.removeClass(this.options.repetitionPanelDisabledClass);
				if ($.browser.msie && $.browser.version == "6.0" ) this.$moveUpButton.removeClass('up_'+this.options.repetitionPanelDisabledClass);
			}
			// mozgatas lefele gomb
			if (position==instances-1) {
				this.$moveDownButton.addClass(this.options.repetitionPanelDisabledClass);
				if ($.browser.msie && $.browser.version == "6.0" ) this.$moveDownButton.addClass('down_'+this.options.repetitionPanelDisabledClass);
			}
			else {
				this.$moveDownButton.removeClass(this.options.repetitionPanelDisabledClass);
				if ($.browser.msie && $.browser.version == "6.0" ) this.$moveDownButton.removeClass('down_'+this.options.repetitionPanelDisabledClass);
			}
			// eltavolitas gomb
			if (instances<=this.options.repeatMin) {
				this.$removeButton.addClass(this.options.repetitionPanelDisabledClass);
				if ($.browser.msie && $.browser.version == "6.0" ) this.$removeButton.addClass('rem_'+this.options.repetitionPanelDisabledClass);
			}
			else {
				this.$removeButton.removeClass(this.options.repetitionPanelDisabledClass);
				if ($.browser.msie && $.browser.version == "6.0" ) this.$removeButton.removeClass('rem_'+this.options.repetitionPanelDisabledClass);
			}
			// hozzaadas gomb
			if (instances>=this.options.repeatMax) {
				this.$addButton.addClass(this.options.repetitionPanelDisabledClass);
				if ($.browser.msie && $.browser.version == "6.0" ) this.$addButton.addClass('add_'+this.options.repetitionPanelDisabledClass);
			}
			else {
				this.$addButton.removeClass(this.options.repetitionPanelDisabledClass);
				if ($.browser.msie && $.browser.version == "6.0" ) this.$addButton.removeClass('add_'+this.options.repetitionPanelDisabledClass);
			}
		},
		/**
		 * Blokk hozzaadasa
		 * @return void
		 */
		addBlock: function() {
			//console.time('addBlock');
			var pform = this.$parentForm.data('pform');
			newBlock = $.extend(true, {}, this);
			newBlock.callProcessor('onBeforeAddBlock');

			// alap modszer
			newBlock.$fieldsetElement = this.$fieldsetElement.clone();
				
			newBlock.addRandomNamesToRadios(newBlock.$fieldsetElement);
			newBlock.$fieldsetElement.insertAfter(this.$fieldsetElement);
			newBlock.$fieldsetElement.data('block', newBlock);
			newBlock.createPanel();
			newBlock.emptyBlock();
			newBlock.isNewblock = true; // emiatt lesznek ujrakotve a mezok
			pform.validator.blocks.push(newBlock);
			// sajat regexp+repetition nem mukodik, mert jquery nem jol klonozza a regexpet, ezt a bugot küszöböli ki valamit http://dev.jquery.com/ticket/4192
			// TODO: jquery bug javítása utan az alabbi ciklus eltavolithato (1.3.2 jq-ben szerepel meg a bug, kesobbi verzioban kellene nezni)
			for (var i in this.fields) {
				newBlock.fields[i].formats = this.fields[i].formats;
				/*
				if ( $.data(this.fields[i].$elements[0], 'datepicker') ) {
					$.data(newBlock.fields[i].$elements[0], 'datepicker', $.data(this.fields[i].$elements[0], 'datepicker') );
				}
				console.log( $.data(newBlock.fields[i].$elements[0], 'datepicker') );
				*/
			}
			this.normalize();
		
			newBlock.callProcessor('onAddBlock');
			//console.timeEnd('addBlock');
		},
		/**
		 * Blokk eltavolitasa
		 * @return void
		 */
		removeBlock : function() {
			var pform = this.$parentForm.data('pform');
			this.callProcessor('onBeforeRemoveBlock');
			this.$fieldsetElement.remove();
			this.normalize();
			//delete this; //@TODO: ie6 alatt nem megy ezért kivettem, van-e mellékhatás?
			for (var i=0; i<pform.validator.blocks.length; i++) {
				if ( pform.validator.blocks[i]==this ) {
					var pos = i;
					break;
				}
			}
			pform.validator.blocks.splice(pos, 1);
			this.callProcessor('onRemoveBlock');
		},
		/**
		 * Blokk mozgatasa le
		 * @return void
		 */
		moveDown: function() {
			this.callProcessor('onBeforeMoveDownBlock');
			this.addRandomNamesToRadios(this.$parentForm);
			
			var $nextFieldsetInstance = this.$fieldsetElement.next('[id^='+this.block_id+']');
			if ($nextFieldsetInstance.length>0) $nextFieldsetInstance.after(this.$fieldsetElement);
			this.normalize();
			this.callProcessor('onMoveDownBlock');
		},
		/**
		 * Blokk mozgatasa fel
		 * @return void
		 */
		moveUp: function() {
			this.callProcessor('onBeforeMoveUpBlock');
			this.addRandomNamesToRadios(this.$parentForm);
			
			var $prevFieldsetInstance = this.$fieldsetElement.prev('[id^='+this.block_id+']');
			if ($prevFieldsetInstance.length>0) $prevFieldsetInstance.before(this.$fieldsetElement);
			this.normalize();
			this.callProcessor('onMoveUpBlock');
		},
		/**
		 * Blokkok normalizalasa (id-k, name-k) rendebetetel
		 * @param {Boolean} ha ez ki van kapcsolva, akkor a convertBlock nem fogja ellenorizni ujra a mezoket konvertalas utan
		 * @return void
		 */
		normalize: function() {
			var pform = this.$parentForm.data('pform');
			for (var i=0; i<pform.validator.blocks.length; i++) {
				if (pform.validator.blocks[i].block_id!=this.block_id) continue;
				var position = pform.validator.blocks[i].getPosition();
				pform.validator.blocks[i].convertBlock(position);
				pform.validator.blocks[i].setPanel(position);
			}
		},
		/**
		 * Blokk uritese
		 * @return void
		 */
		emptyBlock: function() {
			// chekboxokrol es radiokrol leszedjuk a checkedet 
			$('input', this.$fieldsetElement).removeAttr('checked');
			// selected optionok levetele
			$('option', this.$fieldsetElement).removeAttr('selected');
			// ie6,7-ben jquery nem valasztja ki rendesen ha egy selectorral valasztjuk ki
			$("input:text", this.$fieldsetElement).val('');
			$("input:password", this.$fieldsetElement).val('');
			$("select", this.$fieldsetElement).val('');
			$("textarea", this.$fieldsetElement).val('');
		},
		/**
		 * repetition soran jelentkezo radio problema kikuszobolese
		 */
		addRandomNamesToRadios: function($holderElement) {
			var $radios = $("input:radio", $holderElement);
			if ($radios.length==0) return;
			$.each($radios, function() {
				var radio = this;
				var name = radio.name;
				if (name.lastIndexOf('[') > 0) {
					name = name.substr(0, name.lastIndexOf('['));
				}
				newName = name+'['+1+(Math.floor(Math.random(1)*100000))+']';
				radio.name = newName;
				if ($.browser.msie && $.browser.version != "8.0" ) {
					
					if ( $(radio).attr('checked')==true ) {
						var strChecked="checked='checked'";
					} 
					else {
						var strChecked="";
					}
					var newRadioEl = document.createElement('<input type="'+radio.type+'" id="'+radio.id+'" name="' + newName + '" value="' + radio.value + '" '+strChecked+'>');
					var parentNode = radio.parentNode;
					parentNode.insertBefore(newRadioEl, radio);
					parentNode.removeChild(radio);
				}
			});
		},
		/**
		 * Repetition panel elkeszitese
		 * @return void
		 */
		createPanel: function() {
			$('.'+this.options.repetitionPanelClassName, this.$fieldsetElement).remove();
			
			var el = document.createElement(this.options.repetitionPanelTagName);
			el.className=this.options.repetitionPanelClassName;
			this.$repetitionPanelElement = $(el);
			
			var addButton = document.createElement(this.options.repetitionPanelButtonTagName);
			addButton.className = this.options.repetitionPanelAddClass;
			addButton.title = this.options.repetitionPanelAddTitle;
			this.$addButton = $(addButton);	
			
			var removeButton = document.createElement(this.options.repetitionPanelButtonTagName);
			removeButton.className = this.options.repetitionPanelRemoveClass;
			removeButton.title = this.options.repetitionPanelRemoveTitle;
			this.$removeButton = $(removeButton);	
			
			var moveUpButton = document.createElement(this.options.repetitionPanelButtonTagName);
			moveUpButton.className = this.options.repetitionPanelMoveUpClass;
			moveUpButton.title = this.options.repetitionPanelMoveUpTitle;
			this.$moveUpButton = $(moveUpButton);	
			
			var moveDownButton = document.createElement(this.options.repetitionPanelButtonTagName);
			moveDownButton.className = this.options.repetitionPanelMoveDownClass;
			moveDownButton.title = this.options.repetitionPanelMoveDownTitle;
			this.$moveDownButton = $(moveDownButton);	

			$(this.$repetitionPanelElement).append(this.$addButton, this.$removeButton, this.$moveUpButton, this.$moveDownButton);
			
			// esemenykezeles a panel gombjain
			$(el).bind('click', {b:this}, function(e) {
				var $targetEl = $(e.target);
				var block = e.data.b;
				if ($targetEl.hasClass(block.options.repetitionPanelDisabledClass)) return false;
				if ($targetEl.hasClass(block.options.repetitionPanelAddClass)) {
					block.addBlock();	
				}
				else if ($targetEl.hasClass(block.options.repetitionPanelRemoveClass)) {
					block.removeBlock();
				}
				else if ($targetEl.hasClass(block.options.repetitionPanelMoveUpClass)) {
					block.moveUp();
				}
				else if  ($targetEl.hasClass(block.options.repetitionPanelMoveDownClass)) {
					block.moveDown();
				}
			});
			this.$fieldsetElement.append(el);
		}

	});
	
	$.extend($.block, {
		defaultOptions: {
			repetitionIdSeparator: ':',
			repetitionPanelTagName: 'div',
			repetitionPanelClassName: 'repetition_panel',
			repetitionPanelButtonTagName: 'span',
			repetitionPanelAddTitle: 'Blokk hozzáadása',
			repetitionPanelRemoveTitle: 'Blokk eltávolítása',
			repetitionPanelMoveDownTitle: 'Mozgatás le',
			repetitionPanelMoveUpTitle: 'Mozgatás fel',
			repetitionPanelAddClass: 'add',
			repetitionPanelRemoveClass: 'rem',
			repetitionPanelMoveUpClass: 'up',
			repetitionPanelMoveDownClass: 'down',
			repetitionPanelDisabledClass: 'disabled',
			emptyOnRepetition: true,
			repeatMin: 1,
			repeatMax: 5
		}
	});
	
	$.extend($.field.prototype, {
		initialize: function(block) {
			this.$elements = $('#' + this.name);
			// ha id alapjan nem talajuk a validator mezohoz tartozo elemet, akkor name alapjan keressuk, checkboxok, radiok miatt
			if (this.$elements.length == 0) {
				this.$elements = $('input[name=' + this.name + ']');
			}
			// multi checkbox eseten
			if (this.$elements.length == 0) {
				this.$elements = $('input[name=' + this.name + '[]]');
			}
			// repetition eseten
			if (typeof(block.iterator) != 'undefined') {
				if (this.$elements.length == 0) {
					this.$elements = $('#' + this.name + "\\:" + block.iterator, block.$fieldsetElement);
				}
				if (this.$elements.length == 0) {
					this.$elements = $('input[name^=' + this.name + '['+block.iterator+']]');
				}

			}
			if (this.$elements.length == 0) {
				log('hiba: nincs elem a kovetkezo validator mezohoz: ' + this.name, 3);
			}
			this.setElements();
		}
	});
})(jQuery);



