/*global $:true, document:true, window:true,
reloadDocument:true, bindBaseLinks:true, bindInPlaceLinks:true */
$(function() {
    
    var editor = null;
    var hasAutoWidth = null;
    
    function ajaxError(xhr, status) {
        if (editor) {
            editor.stopTime();
        }
        document.write(xhr.responseText);
        document.close();
    }
    
    function serialize(form, extra) {
        var data;
        if (form) {
            data = form.find('form').serialize();
            form.find("input[type='file']").each(function() {
                if (data) {
                    data += '&';
                }
                data += this.name + '=' + this.value;
            });
        } else {
            data = '';
        }
        if (extra) {
            $(extra).each(function() {
                var extra = $(this).serialize();
                if (extra) {
                    if (data) {
                        data += '&';
                    }
                    data += extra;
                }
            });
        }
        return data;
    }
    
    function submit(url, form, extra, valid) {
        editor.oneTime(2000, function() {
            $('body').css('cursor', 'wait');
            $.blockUI({ baseZ: 2000 });
        });
        $.ajax({type: 'POST',
            url: url,
            data: serialize(form, extra),
            error: ajaxError,
            success: function(response) {
                response = $(response);
                if (response.hasClass('in-place-invalid')) {
                    editor.stopTime();
                    $('body').css('cursor', 'auto');
                    $.unblockUI();
                    form.find('.in-place-html').html(response.html());
                } else if (response.hasClass('in-place-valid')) {
                    if (response.hasClass('in-place-redirect')) {
                        window.location = response.text();
                    } else if (response.hasClass('in-place-reload')) {
                        reloadDocument();
                    } else if (response.hasClass('in-place-multipart-submit')) {
                        form = form.find('form');
                        form.unbind('submit');
                        form.submit();
                    } else {
                        editor.stopTime();
                        $('body').css('cursor', 'auto');
                        $.unblockUI();
                        valid();
                        if (response.hasClass('in-place-changed')) {
                            editor.find('.in-place-value').html(response.html());
                        }
                        editor = null;
                    }
                } else {
                    reloadDocument();
                }
            }
        });
    }
    
    function bindButton(editor, name, click) {
        bindBaseLinks(editor);
        editor.find('.in-place-' + name).each(function() {
            $(this).click(click);
        });
    }
     
    function editInline(url, form, extra, saveText, cancelText) {
        var html  = '<div class="ui-corner-all ' + form.attr('class') + '">';
        html     +=    form.html();
        html     += '</div>';
        html     += '<div class="in-place-buttons">';
        html     +=   '<button class="in-place-save storm-button">';
        html     +=      saveText;
        html     +=   '</button>';
        html     +=   '&nbsp;';
        html     +=   '<button class="in-place-cancel storm-button">';
        html     +=      cancelText;
        html     +=   '</button>';
        html     += '</div>';
        editor.data('html', editor.html());
        editor.html(html);
        var inlineSubmit = function () {
            submit(url, editor, extra, function() {
                editor.html(editor.data('html'));
                bindBaseLinks(editor);
                bindInPlaceLinks(editor);
            });
        };
        editor.find("form").submit(function() {
            inlineSubmit();
            return false;
        });
        bindButton(editor, 'save', inlineSubmit);
        bindButton(editor, 'cancel', function() {
            editor.html(editor.data('html'));
            bindBaseLinks(editor);
            bindInPlaceLinks(editor);
            editor = null;
        });
    }
    
    function editDialog(url, modal, width, title, inPlaceForm, extra, saveText, cancelText, refreshSelf) {
        var buttons = {};
        buttons[cancelText] = function() {
            $(this).dialog('destroy');
            $(this).remove();
            editor = null;
        };
        buttons[saveText] = function() {
            var form = $(this);
            submit(url, form, extra, function() {
                form.dialog('destroy');
                form.remove();
            });
        };
        var options = {
            modal: modal,
            title: title,
            height: 'auto',
            minWidth: 0,
            minHeight: 0,
            resizable: false,
            buttons: buttons,
            close: function() {
                $(this).dialog('destroy');
                $(this).remove();
                editor = null;
            }
        };
        if (width) {
            if (!isNaN(width)) {
                options['width'] = parseInt(width);
                width = null;
            }
        } else {
            width = 'auto';
        }
        if (width == 'auto') {
            if (hasAutoWidth === null) {
                var div = $('<div><span style="width:1px;float:right;"></span></div>');
                div.dialog({ width: 'auto' });
                hasAutoWidth = (div.width() == 1);
                div.remove();
            }
            if (hasAutoWidth) {
                options['width'] = 'auto';
                width = null;
            } else {
                width = '.in-place-html';
            }
        }
        if (refreshSelf) {
            // replace the old html
            $(".ui-dialog .in-place-form").html(inPlaceForm.html());
            inPlaceForm = $(".ui-dialog .in-place-form");
            // make sure buttons are bound to the new url
            inPlaceForm.dialog('option', 'buttons', buttons);
        } else {
            inPlaceForm.dialog(options);
        }
        bindBaseLinks(inPlaceForm.get(0));
        inPlaceForm.find('.in-place-refresh-link').click(function () {
            // Find the url this refresh link will use
            var url = $(this).find('.in-place-refresh-url').text();
            var dialog = true;
            $.ajax({type: 'POST',
                url: url + (dialog ? (url.match(/\?/) ? '&' : '?') + 'dialog' : ''),
                data: serialize(null, extra),
                error: ajaxError,
                success: function(response) {
                    showEditor(response, url, dialog, extra, true);
                }
            });
            return false;
        });
        inPlaceForm.find('form').submit(function () {
            var form = $(this).closest('.in-place-form');
            submit(url, form, extra, function() {
                form.dialog('destory');
                form.remove();
            });
            return false;
        });
        if (width) {
            if (width === '.pretty-form') {
                // Trying out a hardcoded min width for the pretty form
                width = inPlaceForm.find(width).width();
                if (width < 370) {
                    width = 370;
                }
            } else {
                width = inPlaceForm.find(width).width();
            }
            if (width) {
                if (!refreshSelf) {
                    inPlaceForm.dialog('option', 'width', width + 80);
                    inPlaceForm.dialog('option', 'position', ['center', 'middle']);
                }
            }
        }
    }
    
    function showEditor(response, url, dialog, extra, refreshSelf) {
        editor.stopTime();
        response = $(response);
        if (response.hasClass('in-place-click')) {
            if (response.hasClass('in-place-redirect')) {
                window.location = response.text();
                return;
            }
            if (response.hasClass('in-place-reload')) {
                reloadDocument();
                return;
            }
            $('body').css('cursor', 'auto');
            $.unblockUI();
            if (response.hasClass('in-place-message')) {
                var message = '<div>';
                message    +=   '<p style="padding-left: 32px;">';
                message    +=     response.html();
                message    +=   '</p>';
                message    += '</div>';
                message = $(message);
                message.dialog({
                    modal: true,
                    resizable: false,
                    open: function() {
                        $(this).closest('.ui-dialog').find('.ui-dialog-titlebar').hide();
                    },
                    buttons: {
                        Ok: function() {
                            $(this).dialog('destroy');
                            $(this).remove();
                        }
                    }
                });
            } else if (response.hasClass('in-place-changed')) {
                editor.find('.in-place-value').html(response.html());
            }
            editor = null;
            return;
        }
        $('body').css('cursor', 'auto');
        $.unblockUI();
        if (response.hasClass('in-place-changed')) {
            editor.find('.in-place-value').html(response.html());
            editor = null;
            return;
        }
        var form = response.find('.in-place-form');
        var saveText = response.find('.in-place-save-text').text();
        if (!saveText) {
            saveText = 'Save';
        }
        var cancelText = response.find('.in-place-cancel-text').text();
        if (!cancelText) {
            cancelText = 'Cancel';
        }
        url += (url.match(/\?/) ? '&' : '?') + 'save';
        if (dialog) {
            var modal = response.hasClass('in-place-modal');
            var width = response.find('.in-place-width').text();
            var title = response.find('.in-place-title').html();
            editDialog(url, modal, width, title, form, extra, saveText, cancelText, refreshSelf);
        } else {
            editInline(url, form, extra, saveText, cancelText);
        }
    }
    
    function edit() {
        $(this).trigger('mouseleave').trigger('blur');
        if (editor) {
            var message = '<div title="Active edit in progress" class="ui-state-error ui-corner-all">';
            message    +=   '<p style="float:left;">';
            message    +=     '<span style="float:left;" class="ui-icon ui-icon-alert"></span>';
            message    +=   '</p>';
            message    +=   '<p style="padding-left: 32px;">';
            message    +=     'Complete the current edit before editing a new item. ';
            message    +=   '</p>';
            message    += '</div>';
            $(message).dialog({modal: true, resizable: false, buttons: {
                Ok: function() {
                    $(this).dialog('destroy');
                    $(this).remove();
                    $(".ui-dialog-buttonpane").effect("highlight", {}, 3000);
                    $(".in-place-buttons").parent().parent().effect("highlight", {}, 3000);
                }
            }});
            return false;
        }
        editor = $(this).closest(".in-place-editor");
        editor.oneTime(2000, function() {
            $('body').css('cursor', 'wait');
            $.blockUI();
        });
        var url = editor.find('.in-place-url').text();
        var dialog = editor.hasClass('in-place-dialog');
        var extra = editor.find('.in-place-form-extra').text();
        $.ajax({type: 'POST',
            url: url + (dialog ? (url.match(/\?/) ? '&' : '?') + 'dialog' : ''),
            data: serialize(null, extra),
            error: ajaxError,
            success: function(response) {
                showEditor(response, url, dialog, extra);
            }
        });
        return false;
    }
    
    function bindInPlaceLinks(context) {
        $('.in-place-link', context).each(function() {
            $(this).mouseenter(function() {
                var link = $(this);
                var title = link.data('title');
                if (editor) {
                    if (title === undefined) {
                        link.data('title', link.attr('title'));
                        link.attr('title', 'Active edit in progress');
                    }
                } else {
                    if (title !== undefined) {
                        link.attr('title', title);
                        link.removeData('title');
                    }
                    if (link.hasClass('in-place-icon')) {
                        link.addClass('ui-state-hover');
                    }
                }
            }).click(edit);
            if ($(this).hasClass('in-place-icon')) {
                $(this).mouseleave(function() {
                    $(this).removeClass('ui-state-hover');
                }).focus(function() {
                    $(this).addClass('ui-state-focus');
                }).blur(function() {
                    $(this).removeClass('ui-state-focus');
                });
            }
        });
    }
    
    bindInPlaceLinks();
    
});
