function processResponse( jsResponse ) {

	var response = eval( jsResponse );
	
	if ( response.reload ) {
		window.location.replace( window.location.href );
	}
	
	return response;

}

function use( id ) {
	return $( id ).retrieve( 'usable' );	
}
	
function normalizedEmpty( value ) {
		if ( value == '' ) {
			return null;
		}
		if ( value == undefined ) {
			return null;
		}
		return value;
}

var FormPanel = new Class({
	
	initialize: function( formElement ) {
	
		this.formElement = $( formElement );
		
		formElement.store( 'usable', this );
	
		this.buttonVisible = false;
		this.elements = [];
		this.initialState = {};
		
		this.elements.combine( formElement.getElements('input') );
		this.elements.combine( formElement.getElements('select') );
		this.elements.combine( formElement.getElements('textarea') );
        	
		this.footer = formElement.getElement( 'div.footer' );
    	this.submitButton = formElement.getElement( 'input.submitButton' );
    	
    	var formPanel = this;
    	
    	this.elements.each( function(el) {
    		this.initialState[ el.name ] = el.value;

    		if ( el.type != 'submit' ) {
    		
    			var eventTypes = [ 'keyup' ];
    			
    			if ( el.get( 'tag' ) == 'select' || ( (el.get( 'tag' ) == 'input') && (el.get( 'type' ) == 'hidden') ) ) {    				
    				eventTypes = [ 'change' ];
    			}
    			else if ( el.get( 'tag' ) == 'input' && el.get( 'class' ) == 'DatePicker' ) {
    				eventTypes = [ 'keyup', 'change' ];
    			}
    			else if ( el.get( 'tag' ) == 'input' && el.get( 'type' ) == 'radio' ) {
    				eventTypes = [ 'change', 'click' ];
    			}
    			
    			eventTypes.each( function ( eventType ) {
		    	    el.addEvent( eventType, function() {
		    	        if ( normalizedEmpty( this.value ) != normalizedEmpty( formPanel.initialState[ this.name ] ) ) {
		    	            formPanel.showSubmitButton();          
		    	        }
		    	        else {
		    	            formPanel.hideSubmitButton();
		    	        }
		    	    });
    			});
    	    
    		}
    	}, this );
    		
    	if ( !formElement.onsubmit ) {
	    	if ( formElement.hasClass('fileUploadEnabled') ) {
	    		formElement.addEvent( 'submit', this.iframeSubmit.pass([],this) );
			}
			else {
				formElement.addEvent( 'submit', this.ajaxSubmit.pass([], this) );
			}
    	}
    	else {
    		formElement.addEvent( 'submit', this.wrappedSubmit.pass( [ formElement.onsubmit ], this ) );
    		formElement.onsubmit = null;
    	}
    	
    	this.statusBar = this.formElement.getElement( '.statusBar' );
    	
    	var fieldErrors = $H({});
    	this.elements.each(function(el) {
    		var parentRow = el.getParent('tr');
    		
    		if ( parentRow ) {
    		
    			var errorCell = parentRow
								.getNext('tr')
								.getElement('.fieldErrors');
    			
    			fieldErrors[ el.name ] = errorCell;
    		}
    	});
    	
    	this.fieldErrors = fieldErrors;
    	
    	this.globalErrors = formElement.getElement( '.globalErrors' );
	},
	
	clearErrors: function() {
		
		this.fieldErrors.each( function ( fieldErrorEl, fieldName ) {			
				fieldErrorEl.set( 'html', '' );
		});
	},
	
	clearError: function( fieldName ) {
		
		var errorCell = this.fieldErrors.get( fieldName ); 
		
		errorCell.set( 'html', '' );
		
		var currHeight = errorCell.getStyle( 'height' ) || 0;
		var targetHeight = 0;
		
		var resizer = errorCell.get( 'tween', { property: 'height', duration: 500 } );
		
		resizer.start( currHeight, targetHeight );
	},
	
	refresh: function() {
		var formPanel = this;
		
		formPanel.elements.each( function(el) {
			
			if ( el.type != 'file' && el.type != 'radio' ) {
				el.value = formPanel.initialState[ el.name ];
			}
		});
		formPanel.hideSubmitButton();
		
	},
	
	rememberState: function() {
		var formPanel = this;
		
		formPanel.elements.each( function(el) {
			
			if ( el.type != 'radio' || el.checked ) {			 
			   formPanel.initialState[ el.name ] = el.value;
			}
		});
		formPanel.hideSubmitButton();
	},
	
	setErrors: function( fieldName, errors ) {
		var errorCell = this.fieldErrors[ fieldName ];		
		
		var currHeight = errorCell.getStyle( 'height' ) || 0;
		var targetHeight = errors.length * 15;
		
		var resizer = errorCell.get( 'tween', { property: 'height', duration: 500 } );
		
		resizer.start( currHeight, targetHeight ).chain( 
			function() { errorCell.set( 'html', errors.join('<br/>') ); }
		);
	},
	
	setStatus: function( statusText ) {
		var statusBar = this.statusBar;
		
		var opacity = statusBar.get( 'tween', { property: 'opacity', duration: 500 } );
		var resizer = statusBar.get( 'tween', { property: 'height', duration: 250 } );
		resizer.start( 0, 15 ).chain(
			function() { 
				opacity.start(0,100);
				statusBar.set( 'text', statusText ); 
			}
		);
	},
	
	clearStatus: function( chainedFunction ) {
		var statusBar = this.statusBar;
		
		if ( normalizedEmpty( statusBar.get( 'html' ) ) != null ) {
			
			var opacity = statusBar.get( 'tween', { property: 'opacity', duration: 500 } );
			var resizer = statusBar.get( 'tween', { property: 'height', duration: 500 } );
			
			opacity.start(0).chain( function() {
				
				statusBar.set( 'html', '' );
				if ( chainedFunction ) {
					resizer.start( 15, 0 ).wait(1000).chain( chainedFunction );
				}
				else {
					resizer.start( 15, 0 );
				}
				
			});
			
		}
		else {
			if ( chainedFunction ) { chainedFunction(); }
		}
		
	},
	
	wrappedSubmit: function( submitFnc ) {
		
		submitFnc();
		
		this.onSuccessfulUpdate( 'ok' ); 
		
		return false;
	},
	
	iframeSubmit: function() {
		
		var formPanel = this;
		var statusBar = this.statusBar;
		
		var postRequestEffects = $H({});
		formPanel.fieldErrors.each( function( item, key ) {
			
			postRequestEffects[ key ] = formPanel.clearError.pass( key, formPanel ); 
			
		} );

		
		this.formElement.target = 'upload_target';
		
		$( 'upload_target' ).addEvent( 'load', function() {
			
			var ret = frames[ 'upload_target' ].document.getElementsByTagName("body")[0].innerHTML;
						
			var response = processResponse( ret );
			
			if ( response.success ) {
				formPanel.onSuccessfulUpdate( response.result );
			}
			else {
			
				$H( response.result.fieldErrors ).each( function( value, key ) {
				
					postRequestEffects[ key ] = formPanel.setErrors.pass([ key, value ], formPanel );
					
				}, 
				formPanel );
		
			}
			
			postRequestEffects.each( function( fn ) { fn(); } );
			
		});
		
		return true;
		
	},
	
	ajaxSubmit: function() {
		
		var formPanel = this;
		var statusBar = this.statusBar;
		
		var postRequestEffects = $H({});
		formPanel.fieldErrors.each( function( item, key ) {
			
			postRequestEffects[ key ] = formPanel.clearError.pass( key, formPanel ); 
			
		} );

		
		var request = new Request({
			url: this.formElement.action, 
			onSuccess: function( jsResponse ) {
				var response = processResponse( jsResponse );
								
				if ( response.success ) {
					formPanel.onSuccessfulUpdate( response.result );
				}
				else {
					
					$H( response.result.fieldErrors ).each( function( value, key ) {
					
						postRequestEffects[ key ] = formPanel.setErrors.pass([ key, value ], formPanel );
						
					}, 
					formPanel );
				}
				
				postRequestEffects.each( function( fn ) { fn(); } );
				
		    }
		});
		
		request.send( this.formElement );
		
		return false;
	},
	
	onSuccessfulUpdate: function( updateResult ) {
		this.rememberState();
		this.setStatus( updateResult );
		
		this.clearStatus.delay( 2000, this );
	},
	
	showSubmitButton: function() {
		if ( !this.buttonVisible ) {
					
			this.buttonVisible = true;
			
			this.submitButton.disabled = false;
			
			var button = this.submitButton;
			var formPanel = this;

			var f = function() {
		    	var resizer = formPanel.footer.get( 'tween', { property: 'height', duration: 750 } );
		    	resizer.start( 45 ).chain(
		    		function() {
		    			var fader = button.get( 'tween', { property: 'opacity', duration: 1500, transition: Fx.Transitions.Cubic.easeIn } );
		    	    	fader.set( 0 );
		    	    	button.setStyle( 'display', 'block' );
		    	    	fader.start( 0, 50 );
		    		}
		    	);
			};
	    	
			this.clearStatus( f );
		}
	},
	
	hideSubmitButton: function() {
				
		if ( this.buttonVisible ) {
		    
	        var hide = true;
	    
	        this.elements.each( function(el) {
	            if ( normalizedEmpty( this.initialState[ el.name ] ) != normalizedEmpty( el.value ) ) {
	                hide = false;
	            }     
	        }, this);
	    
	        if ( hide ) {        	
	        	this.buttonVisible = false;
	        	
	        	this.submitButton.disabled = true;
	        	
	        	var footer = this.footer;
	        	
	        	var fader = this.submitButton.get( 'tween', { property: 'opacity', duration: 1500, transition: Fx.Transitions.Cubic.easeOut } );
	        	fader.start( 50, 0 ).chain( 
					function() {
			        	var resizer = footer.get( 'tween', { property: 'height', duration: 750 } );
			        	
		        		resizer.start( 10 );
					}
				);
	        	
	        	
	        	
	        }
	    }
	}
	
	
});


var ListAndFormPanel = new Class({
	
	Extends: FormPanel,
	
	initialize: function( formElement ) {
		this.parent( formElement );
		
		this.rowIdentifier = 'id';
	},
	
	add: function() {
		
		this.clearInitialState();
		
		this.editedRowId = null;
		this.refresh();
		this.hideDeleteLink();
		this.showForm();
	}, 
	
	clearInitialState: $empty,
	loadInitialState: $empty,
	
	edit: function( id ) {
		
		var request = new Request({
			url: this.formElement.action.replace( 'update=', 'load=' ),
			onSuccess: function ( jsResponse ) {

				var response = processResponse( jsResponse );
				
				if ( response.success ) {
					
					this.loadInitialState( response.result );
		
					this.editedRowId = id;
					
					this.refresh();	
					this.showDeleteLink();
					this.showForm();
				}
			}.bind( this )
		});
		
		var postData = $H({}); postData.set( this.rowIdentifier, id );
		request.post( postData );	
	},
	
	remove: function() {
		
		var request = new Request({
			url: this.formElement.action.replace( 'update=', 'delete=' ),
			onSuccess: function ( jsResponse ) {
				var response = processResponse( jsResponse );
				
				if ( response.success ) {
					this.onSuccessfulUpdate( 'usunięto' );
				}
			}.bind( this )
		});
		
		var postData = $H({}); postData.set( this.rowIdentifier, this.editedRowId );
		request.post( postData );
	},
	
	
	showForm: function() {		
		var alts = this.formElement.getElements( 'div.alternative' );
		
		var fx1 = alts[0].get( 'tween', { property: 'height' } );
		var fx2 = alts[1].get( 'tween', { property: 'height' } );
		fx1.start( 0 ).chain( function() { 
			fx2.start( 135 ).chain( function() {
				alts[1].setStyle( 'overflow', 'visible' );
				alts[1].setStyle( 'height', 'auto' );
			}); 
		});		
	},
	
	showDeleteLink: function() {
		var deleteLink = this.formElement.getElement( 'span.deleteLink' );
		deleteLink.setStyles({ 'display': 'inline', 'visibility': 'visible' });
	},
	
	hideDeleteLink: function() {
		var deleteLink = this.formElement.getElement( 'span.deleteLink' );
		deleteLink.setStyles({ 'display': 'none', 'visibility': 'hidden' });
	},
	
	hideForm: function() {
		var alts = this.formElement.getElements( 'div.alternative' );
		
		alts[1].setStyle( 'overflow', 'hidden' );
		var fx = alts[1].get( 'tween', { property: 'height' } );		
		fx.start( alts[1].getSize().y, 0 ).chain( function() { alts[0].tween( 'height', 20 ); } );
	},	
	
	cancelEdit: function() {
		
		var delay = 0;
		if ( this.buttonVisible ) {
			delay = 2250;
		}
		
		this.refresh();
		this.clearErrors();
		
		this.hideForm.delay( delay, this );
	},
	
	afterReload: function() {},
	
	reload: function() {
		
		new Request({
			url: this.formElement.action.replace( 'update=', 'list=' ),
			onSuccess: function ( jsResponse ) {
				var response = processResponse( jsResponse );
				
				if ( response.success ) {
					this.formElement.getElement('div.reloadTarget').set( 'html', response.result );
				}
				
				this.afterReload();
			}.bind( this )
		})
		.get(this.currentOrder);
		
	}
	
});


function customInputs() {
	
	
	
	$$( 'input.stop-radio-button' ).each( function( radio ) {

		var span = new Element( 'span', {
			'class': ( radio.checked ? 'stop-radio-button-checked' : 'stop-radio-button' ),
			'events': {
				'click': function() {		
					if ( radio.checked ) return;
			
					$( this ).removeClass( 'stop-radio-button' );
					$( this ).addClass( 'stop-radio-button-checked' );
					
					radio.checked = true;
					
					radio.getParent('form')
						.getElements( 'input[name=' + radio.name + ']' )
						.each( function ( anotherRadio ) {
							if ( !anotherRadio.checked ) {
								var anotherSpan = anotherRadio.retrieve( 'alteredBy' );
								anotherSpan.removeClass( 'stop-radio-button-checked' );
								anotherSpan.addClass( 'stop-radio-button' );
							}
						});
					
					radio.fireEvent( 'click' );
		        }
			}
		});
				
		span.inject(radio, 'after');
		radio.store( 'alteredBy', span );
	});
}
