var ajaxform_seq = 1;

$.fn.ajaxForm = function(options) {

    var opts = null;
    var form = $(this);
    var defaults = {}
    var form_url = null;
    var reload_event = 'reload_page';

    /**
     *  Constructor; Initializes form and add submit events
     */
    var __init__ = function() {

        opts = $.extend({}, defaults, options);
        form_url = form.attr('action');
        form.unbind('submit');
        
        // check if a custom reload event was specified
        var rel_attr = form.attr('rel');
        if (rel_attr != null) {
            reload_event = rel_attr;        
        }

 

        
        $(form).bind('submit', function() {
            
            if (form.find(':file').length != 0) {
                iframe_submit();
                // important: DONT RETURN FALSE, OTHERWISE THE FORM WONT COMMIT
            } else {
                
                ajax_submit();
                
                return false;
            }
            
        });
    };

    /*
     * Sends form data as zerialized Array with an AJAX-Post-Request
     */
    var ajax_submit = function() {
       
       
        $.ajax( {
            type : 'POST',
            url : form_url,
            dataType : 'html',
            data : form.serializeArray(),
            beforeSend: function() {
                // neccessary bugfix, as otherwise the form would be initialized
                // with the old form url, and not with the form url of the new form
                // loaded from the server
                var parent = form.parent();
                form.remove();
                display_loader(parent);         
                 
            },
            success : function(response) {
               
                set_content(response);
                
            }
        });
    };

 

    /**
     *  creates an invisible iframe with id iid and name iname and adds it to the DOM
     *   - if iname is not given iid will be used for name also  
     */
    var create_iframe = function(iid, iname) {
        if (iname == undefined)
            iname = iid;
            
        var iframe;
        try {
            // IE HACK
            iframe = $.create('<iframe style="display:none;position: relative; left: -500px" name="' + iname +'" id="' + iid + '" src=""></iframe>',{});
        } catch (ex) {
            /*iframe = $.create('iframe', {
                    src : '',
                    //style : 'display:none; position: relative; left: -500px',
                    style: 'border: 3px solid red;',                    
                    name : iname,
                    id : iid
            });*/
            iframe = $('<iframe style="display:none;position: relative; left: -500px" name="' + iname +'" id="' + iid + '" src=""></iframe>');
            
        }
        iframe.appendTo(document.body);
        //alert(iid);
        //alert(iname);
        return iframe;
    };

    /**
     * iframe garbage collector - removes the iframe from the DOM sometime
     */
    var unregister_iframe = function(iframe) {
    
        var gc = function() {
            iframe.remove();
        };
    
        setTimeout(gc, 300);
    };

    /*
     * Sends the form data in a invinsible Iframe. (Needed for
     * file-uploads).
     */
    var iframe_submit = function() {
    
        remoter_id = 'remoter' + (ajaxform_seq++);
        var iframe = create_iframe(remoter_id);
        
        form.attr('target', remoter_id);
        
       
        iframe.load(function() {
            //setTimeOut(function() {}, 1);
            var a = $(iframe.contents().children()[0]);
            set_content(a.html());
            unregister_iframe(iframe);
        });
        
    };

    // call constructor
    __init__();


    var set_content = function(content) {
        
        if ($.isFunction(opts.update)) {
           opts.update(content);
        } else {
            $(opts.update).replaceWith(content);
        }
        $(document).trigger(reload_event);
    }

 };



/*
 *	AjaxForm supplies AJAX functionality for forms, including fileuploads
 */

AjaxForm = function(selector, opts) {

	var form = null;
	var update_elem = null;

	/*
	 * Sends form data as zerialized Array with an AJAX-Post-Request
	 */
	var ajax_submit = function() {
		display_loader(); 
		$.ajax( {
			type : 'POST',
			url : form.attr('action'),
			dataType : 'html',
			data : form.serializeArray(),
			success : function(response) {
                
				$(update_elem).replaceWith(response);
                
			}
		});
	}
	

	
	/*
	 *  Displays loading animation  
	 */
	var display_loader = function() {
		
		form.css( {
			'position' : 'relative'
		});

		var loader = $.create('span', {}, ['&nbsp;']);
		loader.attr('class', 'form_loader');
		
		form.append(loader);
		
	}

	/*
	 * Sends the form data in a invinsible Iframe. (Needed for
	 * file-uploads). 
	 */
	var iframe_submit = function() {
		
		display_loader(); 
		
		
		var iframe;
		try {
			// IE HACK
			iframe = $.create('<iframe style="display:none;" name="upload_target", id="iframe_test" src=""></iframe>',{});
		} catch (ex) {
			iframe = $.create('iframe', {
				src : '',
				style : 'display:none',
				name : 'upload_target',
				id : 'iframe_test'
			});
		}
		
		
		iframe.insertAfter(form);
		form.attr('target', 'upload_target');
		
		
			
		$('#iframe_test').load( function() {
			var a = $($(this).contents().children()[0]);
			$(opts.update).html(a.find(opts.update).html());
		});
	}

	function __init__() {
		form = $(selector);
        
		update_elem = opts.update;
        
		// bind submit event to form
		$(form).bind('submit', function() {
           
			if (form.find(':file').size() != 0) {
				// in case form has a file-upload field
				iframe_submit();
				
			} else {
				// form without fileupload fields
				ajax_submit();
				return false;
			}

		});

	}
	__init__();

}

