(function($) {
    $.fn.form = function(options) {
        var opts = $.extend($.fn.form.defaults, options);

        if (typeof $.fn.scrollTo == "undefined") {
            var scriptObj = document.createElement("script");

            scriptObj.src = "/js/jquery.scrollTo.js";
            scriptObj.type = "text/javascript";

            var head=document.getElementsByTagName("head")[0];

            head.insertBefore(scriptObj,head.firstChild);
        }

        return this.each(function(){
            $this = $(this);
            $.fn.form.defaults.form = $(this).closest('form');
            $.fn.form.setupFormSubmit($this);
        });
    };

    $.fn.form.setupFormSubmit = function(button) {
        $(button).data($.fn.form.defaults);
        $(button).bind('click', function(){
            $.fn.form.defaults = $(this).data();
            $.fn.form.submitForm(button);
            return true;
        });
    };

    $.fn.form.submitForm = function(button) {
        var data = $($.fn.form.defaults.form).serialize();
        $.each($.fn.form.defaults.extraParams,function(i, element) {
            data += '&' + i + '=' + element;
        });

        $.ajax({
            type: 'POST',
            dataType: 'json',
            url: $.fn.form.defaults.submitUrl,
            data: data,
            success: function(jsonData){
                $.fn.form.removeErrorMessages();

                var callback = $.fn.form.defaults.processFunction;
                if ($.isFunction(callback)) {
                    if (callback(jsonData) == true) {
                        $.fn.form.removeLoadingAnimation(button);
                    }
                }
            },
            beforeSend: function(){
                $.fn.form.addLoadingAnimation(button);
            }
        });
    };

    $.fn.form.processResult = function(data) {
        if (data.formErrors) {
            $.fn.form.formErrors(data.formErrors);
        }

        if (data.load) {
            $.fn.form.loadContent(data.load);
        }

        if (data.replace) {
            $.fn.form.replaceContent(data.replace);
        }

        if (data.setElement) {
            $.fn.form.setElement(data.setElement);
        }

        if (data.notification) {
            $.fn.form.displayNotification(data.notification);
        }        

        if (data.removeItem) {
            $.fn.form.removeItem(data.removeItem.target);
        }

        if (data.addItem) {
            $.fn.form.addItem(data.addItem.target);
        }

        if (data.highlight) {
            $.fn.form.highlight(data.highlight.target);
        }

        if (data.append) {
            $.fn.form.append(data.append.target, data.append.content);
        }

        if (data.after) {
            $.fn.form.after(data.after.target, data.after.content);
        }

        if (data.callback) {
            eval(data.callback);
        }

        if (data.chain) {
            $.fn.form.chainRequests(data.chain);
        }

        if (data.refresh) {
            window.location.reload();
        }

        if (data.redirect) {
            $.fn.form.redirect(data.redirect.location);
        }

        return true;
    };

    $.fn.form.initEditor = function(element) {
        $(element).tinymce({
            // Location of TinyMCE script
            script_url : '/js/tiny_mce/tiny_mce.js',

            // General options
            theme : "advanced",
            skin : "cirkuit",
            mode : "specific_textareas",
            document_base_url : "",
            relative_urls : false,
            convert_urls: false,
            /*plugins : "pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,advlist",

            // Theme options
            theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect",
            theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
            theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
            theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak",*/

            plugins : "style,save,advhr,advimage,advlink,media,paste,fullscreen,advlist",

            // Theme options
            theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontsizeselect,|,forecolor,backcolor,|,bullist,numlist",
            theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,cleanup,|,hr,removeformat,|,sub,sup,|,charmap,media,code",
            theme_advanced_buttons3 : "",
            theme_advanced_toolbar_location : "top",
            theme_advanced_toolbar_align : "left",
            theme_advanced_statusbar_location : "bottom",
            theme_advanced_resizing : true,

            // Example content CSS (should be your site CSS)
            content_css : "/css/admin/styles.css"
        });
    }

    $.fn.form.initTinyEditor = function(element) {
        $(element).tinymce({
            // Location of TinyMCE script
            script_url : '/js/tiny_mce/tiny_mce.js',

            // General options
            theme : "advanced",
            skin : "cirkuit",
            mode : "specific_textareas",
            document_base_url : "",
            relative_urls : false,
            convert_urls: false,
            /*plugins : "pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,advlist",

            // Theme options
            theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect",
            theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
            theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
            theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak",*/

            plugins : "style,save,advhr,advimage,advlink,media,paste,fullscreen,advlist",

            // Theme options
            theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontsizeselect",
            theme_advanced_buttons2 : "forecolor,backcolor,|,cut,copy,paste,pastetext,pasteword,|,outdent,indent,|,undo,redo",
            theme_advanced_buttons3 : "link,unlink,anchor,cleanup,help,|,hr,removeformat,|,sub,sup,|,charmap,media,code",
            theme_advanced_toolbar_location : "top",
            theme_advanced_toolbar_align : "left",
            theme_advanced_statusbar_location : "bottom",
            theme_advanced_resizing : true,

            // Example content CSS (should be your site CSS)
            content_css : "/css/admin/styles.css"
        });
    }

    $.fn.form.loadContent = function(loadContent) {
        var targets = loadContent.target.split(',');
        $.each(targets, function(i, item) {
            $(item).html(loadContent.content);
        });
    }

    $.fn.form.replaceContent = function(replaceContent) {
        var targets = replaceContent.target.split(',');
        $.each(targets, function(i, item) {
            $(item).replaceWith(replaceContent.content);
        });
    }

    $.fn.form.setElement = function(setElement) {
        var targets = setElement.target.split(',');
        $.each(targets, function(i, item) {
            $(item).val(setElement.content);
        });
    }

    $.fn.form.formErrors = function(errors) {
        var fieldLabels = new Array();
        var errorCount = 0;
        $.each(errors, function(i,item){
            $.fn.form.addErrorMessages(i, item);
            if (errorCount == 0 && typeof $.fn.scrollTo != "undefined") {
                $.scrollTo('#' + i, 800, {margin:true, offset: -25});
                errorCount = 1;
            }
        });

        var errorFields = fieldLabels.join(', ');
        errorFields = errorFields.substring(0, (errorFields.length-2));
    }

    $.fn.form.chainRequests = function(requestOptions) {
        $.ajax({
            type: 'POST',
            dataType: 'json',
            url: requestOptions.url,
            data: requestOptions.data,
            success: function(jsonData){
                $.fn.form.processResult(jsonData);
            }
        });
    }

    $.fn.form.removeItem = function(target) {
        $(target).fadeOut('normal', function(){$(this).remove();});
    }

    $.fn.form.addItem = function(target) {
        $(target).fadeIn('normal', function(){  });
    }

    $.fn.form.highlight = function(target) {
        $(target).effect('highlight', {color: '#FCEFA1'}, 3000);
    }

    $.fn.form.append = function(target, content) {
        $(target).append(content);
    }

    $.fn.form.after = function(target, content) {
        $(target).after(content);
    }

    $.fn.form.displayNotification = function(notification) {
        var targets = notification.target.split(',');
        $.each(targets, function(i, item) {
            $.fn.form.append(item, notification.content);
            $(item).children().last().delay(4000).slideUp('normal', function(){$(this).remove();});
        });
    }

    $.fn.form.addErrorMessages = function(element, messages) {
        var errorMessages = '';
        $.each(messages, function(i, item){
            errorMessages += '<li class="formerror">' + item + '</li>';
        });

        $('#' + element).after('<ul class="errors">' + errorMessages + '</ul>');

    }

    $.fn.form.removeErrorMessages = function() {
        $('.errors').remove();
    }

    $.fn.form.addLoadingAnimation = function(button) {
        if ($.fn.form.defaults.disableButtons == true) {
            $('button').attr('disabled', 'disabled');
        }

        var image = '<img class="loading" src="' + $.fn.form.defaults.animationImage + '" alt="Loading..." />';

        if ($.fn.form.defaults.customObjectForAnimation == '') {
            $button = $(button);
        } else {
            $button = $.fn.form.defaults.customObjectForAnimation;
        }

        if ($.fn.form.defaults.animationLocation == 'before') {
            $($button).before(image);
        } else if($.fn.form.defaults.animationLocation == 'after') {
            $($button).after(image);
        }
    }

    $.fn.form.removeLoadingAnimation = function(button) {
        if ($.fn.form.defaults.disableButtons == true) {
            $('button').removeAttr('disabled');
        }

        $('.loading').remove();
    }

    $.fn.form.redirect = function(location) {
        window.location.href = location;
    }

    $.fn.form.cleanUp = function() {
        $.fn.form.removeLoadingAnimation();
    }

    $.fn.form.defaults = {
        showLoadingAnimation: true,
        animationLocation: 'after',
        animationImage: '/images/admin/loading.png',
        customObjectForAnimation: '',
        disableButtons: true,
        submitType: 'POST',
        submitUrl: '',
        form: '',
        dataType: 'json',
        processFunction: $.fn.form.processResult,
        extraParams: {},
        data: {}
    };

    $.fn.form.origDefaults = {};
})(jQuery);
