/**
 * Provides interactivity for the booking form
 *
 * @author PK
 * @requires jquery-1.3.2.min.js
 * @requires jquery.form-2.28.js
 * @requires Form.js
 * @requires BookingFormHTMLProvider.js
 */
var BookingFormInterface = function()
{
    // quick check for jquery
    if (typeof($) == 'undefined') throw new Error('jQuery not included properly');

    return {
        bookingForm : new BookingForm(),
        currentpage : 0,
        lastpage : null,
        email : null,
        mdlink : '/',
        texts : {},
        sessionData : null,

        setText : function(name, text) {
            this.texts[name] = text;
        },

        getText : function(name) {
            return this.texts[name];
        },

        setMDLink : function(link) {
            this.mdlink = link;
        },

        setSessionData : function(session) {
            this.sessionData = session;
        },

        onUnload : function() {
            return 'Als u weg navigeert van deze pagina raken al uw ingevulde gegevens verloren, weet u zeker dat u deze pagina wilt verlaten?';
        },

        onTimeout : function() {
            this.showDialog('Het ophalen van informatie duurt langer dan gebruikelijk, een ogenblik geduld alstublieft.');
        },

        onConnectionFailed : function() {

            // display dialog with notification and provide a way to manually submit the form
            var value = '';
            var phone = $('#frmaddress_1_frmphone');
            if (phone.length) {
                value = phone.val();
            }

            var html = '<p>Op dit moment zijn er problemen met de connectie met ons boekingssysteem. Neem contact op met Djoser (071-512 64 00) of probeer het later nog eens. Onze excuses voor dit ongemak.</p>';
            html += '<form id="call-me-back"><p><input class="button" type="submit" value="Verstuur reeds ingevulde gegevens"/></p></form>';

            this.showDialog(html, true);

            var that = this;
            $('#call-me-back').submit(function() { that.callMeBack(); return false; });

        },

        addExtraInfoLinks : function() {

            var link = '';
            var parentInput = '';

            // ceasing insurance option
            parentInput = $('input[name$="frminsurance_type"][value$="ceasing"]').parent();
            link = '<a href="/verzekeringen/overzicht/de_reisverzekering/" class="extra-info" rel="external" target="_blank">?</a>';
            $(link).appendTo(parentInput);

            // continuing insurance option
            parentInput = $('input[name$="frminsurance_type"][value$="continuing"]').parent();
            link = '<a href="/verzekeringen/overzicht/doorlopende_reisverzekering/" class="extra-info" rel="external" target="_blank">?</a>';
            $(link).appendTo(parentInput);

            // ceasing cancellation option
            parentInput = $('input[name$="frmcancellation_insurance"][value$="ceasing"]').parent();
            link = '<a href="/verzekeringen/overzicht/de_annuleringsverzekering/" class="extra-info" rel="external" target="_blank">?</a>';
            $(link).appendTo(parentInput);

            // continuing cancellation option
            parentInput = $('input[name$="frmcancellation_insurance"][value$="continuing"]').parent();
            link = '<a href="/verzekeringen/overzicht/de_doorlopende_annuleringsverzekering/" class="extra-info" rel="external" target="_blank">?</a>';
            $(link).appendTo(parentInput);

            // warranty cancellation option
            parentInput = $('input[name$="frmcancellation_insurance_extensions[warranty]"]').parent();
            link = '<a title="Annulering of Garantie-Annulering: aan jou de keus<br/><br/>Met Garantie-Annulering gaan we nog een stap verder. Mocht je je reis moeten afbreken, dan vergoeden we zelfs de hele reissom in plaats van alleen de niet-genoten reisdagen, ook als je maar een deel van de reis mist! En dat is een prettige zekerheid. Hiervoor betaal je 0,5% extra premie." class="extra-info">?</a>';
            $(link).appendTo(parentInput);

            // observer cancellation option
            parentInput = $('input[name$="frmcancellation_insurance_extensions[observer]"]').parent();
            link = '<a title="Waarnemer<br/><br/>Voor 1% extra premie per waarnemer kun je iedereen meeverzekeren die je reden kunnen geven niet op reis te gaan of naar huis terug te keren. Bijvoorbeeld een dierbare die geen familielid in eerste of tweede graad is, degene die op je huis en huisdieren past of de persoon die je zaken waarneemt tijdens de vakantie." class="extra-info">?</a>';
            $(link).appendTo(parentInput);

            // observer cancellation option
            parentInput = $('input[name$="frmdiscount_code"]').parent();
            if (parentInput.attr("class") != 'nodisplay') {
                link = '<a title="Indien van toepassing kunt u hier de actiecode invullen. Klik vervolgens op de knop \'Bevestig actiecode\' en vul de code nogmaals in." class="extra-info">?</a>';
                $(link).appendTo(parentInput.prev());
            }

        },

        displayExtraInfo : function(e) {

            var that = this;
            var href = e.target.href;
            var title = e.target.title;
            var dialog = $('#dialog');

            if (href) {
                dialog.parent().addClass('iframe-popup');
                var html = '<iframe width="100%" height="100%" scrolling="auto" src="' + href + '"></iframe>';
            } else if (title) {
                var html = title;
            }

            dialog.html(html);
            dialog.dialog('open');

            e.stopPropagation();
            e.preventDefault();

        },

        showLoginForm : function(result) {

            var that = this;

            var fn = function(result) {
                var forgotpass = '<a id="forgotpass" title="Wachtwoord vergeten" style="display: inline;">Wachtwoord vergeten</a>';
//                that.showDialog(that.getText('MyBookingFormDjoserAccountDescription') + result.page_data.formerrorhtml + result.page_data.formhtml + forgotpass, true);
                var loginform = '<div class="loginform-container"><h2>' + that.getText('MyBookingFormDjoserAccountTitle') + '</h2>' + that.getText('MyBookingFormDjoserAccountDescription') + result.page_data.formerrorhtml + result.page_data.formhtml + forgotpass + '</div>';
                $('#bookingform-steps').prepend(loginform);
                $('#dialog #frmemail').val($('#frmusername').val());
                $('#dialog #frmpassword').val($('#frmpassword').val());
                $('#frm_login').submit(function() { that.requestLogin(); return false; });
//                $('#frm_forgotpassword').submit(function() { that.requestPasswordResetCode(); return false; });
                $('#forgotpass').click(function() { that.requestPasswordResetCode(); });
            };

            if (result) {
                fn.apply(this, [result]);
            } else {
                $.get('/?module=My&action=Login&output=json', null, fn, 'json');
            }
        },

        hideLoginForm : function() {
            $('#bookingform-steps .loginform-container').remove();
        },

        requestLogin : function(form) {

            var that = this;

            // get the form inputs
            var qs = $('#frm_login').formSerialize();
            var email = $('#frmemail').val();
            var password = $('#frmpassword').val();
            var username = $('#frm_login :text').fieldValue()[0];
            if (username) {
                this.email = username;
            }
            $.post('/?module=My&action=Login&referer=bookingform&output=json', qs, function(result, stat) { that.onLoginRequested(result, email, password); }, 'json');

            this.showDialog('');

        },

        onLoginRequested : function(result, email, password) {
            if (result.page_data.handled == true) {
                this.showLoginSucceedForm(null);
            } else {
                // show errors
                this.hideDialog();
                this.hideLoginForm();
                this.showLoginForm(result);

            }
        },

        showLoginSucceedForm : function(result) {
            this.showDialog('');
            $('.login_toggle').addClass('nodisplay');
            $('#frmaddress_1_frmemail').val(this.email);
            $('#frmpersonalia_1_frmusername').val(this.email);

            // make sure the 'no'-option is selected
            var radio = $('input[name="frmpersonalia_1_frmcreate_my_djoser_account"]');
            radio.filter('[value=0]').attr('checked', true);

            $('input[name="frmpersonalia_1_frmpassword"]').parent().parent().hide();
            $('input[name="frmpersonalia_1_frmpassword2"]').parent().parent().hide();

            $('.loginform-container').html('<h2>' + this.getText('MyBookingFormDjoserAccountTitle') + '</h2>' + this.getText('MyBookingFormDjoserAccountLoggedIn'));

            this.bookingForm.updateContactFieldsProvider();

        },

        showForgotPasswordForm : function(result) {

            var that = this;

            var fn = function(result) {
                that.showDialog(that.getText('MyBookingFormForgotPasswordBody') + result.page_data.formerrorhtml + result.page_data.formhtml, true);
                $('#dialog #frmemail').val($('#frmusername').val());
                $('#frm_forgotpassword').submit(function() { that.requestPasswordResetCode(); return false; });
            };

            if (result) {
                fn.apply(this, [result]);
            } else {
                $.get('/?module=My&action=ForgotPassword&output=json', null, fn, 'json');
            }
        },

        requestPasswordResetCode : function(form) {

            var that = this;

            // get the form inputs
            var qs = $('#frm_forgotpassword').formSerialize();
            var email = $('#frmemail').val();
            $.post('/?module=My&action=ForgotPassword&referer=bookingform&output=json', qs, function(result, stat) { that.onPasswordResetCodeRequested(result, email); }, 'json');

            this.showDialog('');

        },

        onPasswordResetCodeRequested : function(result, email) {

            if (result.page_data.handled == true) {
                this.showResetPasswordForm(null, email);
            } else {

                // show errors
                this.showForgotPasswordForm(result);

            }
        },

        showResetPasswordForm : function(result, email) {

            var that = this;

            var fn = function(result) {
                that.showDialog(that.getText('MyBookingFormResetPasswordBody') + result.page_data.formerrorhtml + result.page_data.formhtml, true);
                $('#dialog #frmusername').val(email);
                $('#frm_resetpassword').submit(function() { that.resetPassword(); return false; });
            };

            if (result) {
                fn.call(this, result, email);
            } else {
                $.get('/?module=My&action=ResetPassword&frmusername=' + email + '&output=json', null, fn, 'json');
            }
        },

        resetPassword : function() {

            var that = this;

            // get the form inputs
            var qs = $('#frm_resetpassword').formSerialize();
            var email = $('#frm_resetpassword').find('#frmusername').val();
            var password = $('#frm_resetpassword').find('#frmpassword').val();
            $.post('/?module=My&action=ResetPassword&output=json', qs, function(result, stat) { that.onResetPassword(result, email, password); }, 'json');

            this.showDialog('');

        },

        onResetPassword : function(result, email, password) {

            if (result.page_data.handled == true) {

                // go back to userform with filled in user data
                this.showLoginSucceedForm(null);
                // submit form to proceed to the next step
//                var form = this.bookingForm.getFormObject(this.currentpage);
//
//                // submit the form
//                $('#frmusername').val(email);
//                $('#frmpassword').val(password);
//                form.find(':submit').click();

            } else {

                // show errors
                this.showResetPasswordForm(result, email);

            }
        },

        /**
         * Displays form errors on the screen
         *
         * @param {Form}    The form that contains errors
         */
        onFormError : function(form) {

            // clear errors
            this.clearErrors();

            // add the errors
            var errors = form.getErrors();

            // leave out errors for inactive fields
            var element;
            var activeErrors = {};
            for (var a in errors) {

                element = form.getElement(a);

                if (element.isActive()) {
                    activeErrors[a] = errors[a];
                }
            }

            $('#formcontainer').prepend($(BookingFormHTMLProvider.renderFormErrorHTML(form, activeErrors)).addClass('nodisplay'));

            // now show 'em
            this.showErrors();
        },

        clearErrors : function() {
            $('ul.errors').remove();
        },

        showErrors : function() {
            $('ul.errors').show();
        },

        hideErrors : function() {
            $('ul.errors').hide();
        },

        setArrangementsData : function(data) {
            this.bookingForm.arrangementsData = data;
        },

        setElementDependencies : function(dependencies) {
            this.bookingForm.dependencies = dependencies;
        },


        /**
         * Sets previous/current/next steps in the sidebar
         *
         * @param {Object}  formpages   Object containing pagenum => form
         */
        updateSideBar : function(formpages) {

            var that = this;
            var provider = BookingFormHTMLProvider;
            var contents;

            // create tiny form
            var basicstepform = '<form action="/?module=DJO&amp;action=BookTrip" method="post" class="bookingform-step">';
            // loop through pages and fields
            for (var pagenum in formpages) {
                for (var field in formpages[pagenum].form.fields) {
                    if (formpages[pagenum].form.fields[field].type == 'hidden' && (formpages[pagenum].form.fields[field].name != 'prevpage' && formpages[pagenum].form.fields[field].name != 'currentpage')) {
                        var stepfield = '';
                        stepfield = '<input type="hidden" name="'+formpages[pagenum].form.fields[field].name+'" value="'+formpages[pagenum].form.fields[field].value+'" />';
                        basicstepform += stepfield;
                    }
                }
            }

            // create steps if they're not here already
            if (!$('#bookingform-steps').length) {

                var attrs;
                var li = [];
                var currentpage = this.currentpage;
                for (var pagenum in formpages) {

                    var stepform = basicstepform;

                    if (pagenum < currentpage) {

                        if (pagenum == (currentpage-1)) {
                            var backform = stepform;
                            backform += '<input type="hidden" name="newcurrentpage" value="' + (pagenum-1) + '" />';
                            backform += '<input type="submit" class="button submit" value="<<< Vorige">';
                            backform += '</form>';

                            if (pagenum == 1) {
                                $('div.backbutton').html('<a href="/?module=DJO&action=BookTrip"><<< Vorige</a>');
                            } else {
                                $('div.backbutton').html(backform);
                            }

                            if (pagenum == 3) {
                                $('div.printbutton').html('<a>Print</a>');
                                $('#printbutton a').click(function() { window.print(); return false; });
                            }
                        }

                        if (pagenum > 1) {
                            stepform += '<input type="hidden" name="newcurrentpage" value="' + (pagenum-1) + '" />';
                            stepform += '<input type="submit" class="stepform-submit" value="' + formpages[pagenum].title + '">';
                            stepform += '</form>';
                            contents = stepform;
                        } else {
                            contents = '<a class="stepform-link" href="/?module=DJO&amp;action=BookTrip">' + formpages[pagenum].title + '</a>';
                        }
                        contents += provider.getHTMLTag('h3', {'id' : 'page-' + pagenum, 'class' : 'stepform-header'}, '&nbsp;');
                    } else {
                        contents = provider.getHTMLTag('h3', {'id' : 'page-' + pagenum}, formpages[pagenum].title);
                    }

                    contents += '<div class="details"></div>';

                    attrs = {'id' : 'step-' + pagenum};
                    li.push(['li', attrs, contents]);
                }

                $('#aside').prepend(provider.getHTMLTag('ul', {'id' : 'bookingform-steps'}, li));

            }

            // now update the active list item
            for (var pagenum in formpages) {

                var step = $('#step-' + pagenum);

                if (pagenum < this.currentpage) {

                    // previous step: mark completed
                    step.attr('class', 'completed');

                    // update details
                    var prevForm = formpages[pagenum].form;
                    var currentForm = formpages[this.currentpage].form;
                    contents = null;
                    switch (Number(pagenum)) {
                        case 1: contents = provider.getTripInfo(prevForm, currentForm); break;
                        case 2: contents = provider.getParticipantData(prevForm, currentForm); break;
                        case 3: contents = provider.getTripOptions(prevForm, currentForm); break;
                        case 4: contents = ''; break;
                        case 5: contents = ''; break;
                        default: break;
                    }

                    if (contents !== null) {

                        // empty details
                        var details = step.find('.details');
                        details.html(contents);
                        details.slideDown();

                    }

                } else if (pagenum == this.currentpage) {

                    // current step: mark active
                    step.attr('class', 'active');

                    if (step.length) {

                        // now calculate the top offset of the active list item
                        var position = step.position();
                        var padding = parseInt(step.css('padding-bottom'));
                        var top = position.top - padding;

                        // reposition the slider
                        $('#stepslider').animate({'top' : (top + 'px')}, 'fast');

                    }

                } else {

                    // next step: don't mark
                    step.attr('class', '');
                }
            }
        },

        setFormData : function(formdata) {

            var that = this;

            // get (the new) current and last page
            var newpage = formdata.currentpage;
            this.lastpage = formdata.last_formpage;

            var formpage = null;

            // look for formpages
            if ('formpages' in formdata) {
                for (var pagenum in formdata.formpages) {

                    // get the formpage, and add it to the booking form
                    formpage = formdata.formpages[pagenum];
                    var form = this.bookingForm.addFormpage(pagenum, formpage.form, formpage.title);

                    // get the new page
                    if (pagenum == newpage) {

                        // see if page has changed (if not: we have to show errors)
                        var changePage = false;
                        var prevPage = form.getElement('prevpage');
                        if (prevPage && (prevPage.getValue() != newpage)) {
                            changePage = true;
                        }

                        // set json output as hidden element in the form
                        if (!('output' in form.getElements())) {
                            var field = form.addElement({'type' : 'hidden', 'name' : 'json', 'value' : '1'});
                            form.fields[field.getName()] = field;
                        }

                        // replace element 'proceed' with hidden input (this is only needed in non js version)
                        var element = form.getElement('frmproceed');
                        if (element) {
                            element.type = 'hidden';
                            element.value = 1;
                            element.html = '';
                        }


                        // display the form
                        this.displayForm(pagenum, '#formcontainer', changePage);

                        // perform validation before submitting
                        this.bookingForm.getFormObject(newpage).submit(function() { return that.submitForm(newpage); });

                    }
                }
            }

            // set the new current page
            this.currentpage = newpage;

            // update sidebar
            this.updateSideBar(this.bookingForm.formpages);

        },

        fillSessionData : function() {

            var session = this.sessionData;
            for (field in session) {

                var name = field;
                var value = session[name];
                var input = $('#'+name);

                if (input.length > 0) {
                    input.val(value);
                } else {
                    // try to find by name
                    var input = $('input[name="'+name+'"]');

                    if (input.length != 0) {

                        for(var j = 0; j < input.length; j++) {
                            var item = input[j];
                            if (item.value == value) {
                                item.checked = true;
                            }
                        }
                    }
                }

            }

        },

        /**
         * Renders form html on screen
         */
        displayForm : function(formPage, selector, newPage) {

            // get the element we attach the form to
            var obj = $(selector);
            if (obj.length) {

                var form = this.bookingForm.getForm(formPage);

                if (form) {

                    // draw the form
                    this.bookingForm.draw(formPage, obj, true);

                    // empty cookie if it's the first page
                    if (formPage <= 1) {
//                        this.clearCookies();
                    }

                    // set values
                    this.fillSessionData();
//                    this.fillValues(form);

                    this.bookingForm.checkElementDependencies(form.getElementsArray(), true);

                    var that = this;
                    var callback = function() {

                        if ($.browser.msie) {
                            that.clearFilterCallback.apply(this);
                        }

                        // scroll to top of page to show form errors
                        $('html').animate({'scrollTop' : 0}, 200);

                        // show errors (if any)
                        if (!newPage) {
                            that.onFormError(form);
                        }

                    };

                    // drop it like it's hoooot
                    obj.show('drop', {'direction' : 'right', 'easing' : 'easeOutBack'}, 'slow', callback);

                    // add info-links
                    that.addExtraInfoLinks();

                    that.initDiscount();

                    // bind info-windows
                    $('.extra-info').live('click', function(e) { that.displayExtraInfo(e); } );

                }
            }
        },

        /**
         * Submits the form
         *
         * @param {Form}    form
         */
        submitForm : function(formPage) {

            this.hideErrors();

//            this is why username is empty or wrong
//            if ($('#frmusername').val() != '' && $('#frmaddress_1_frmemail').val() == '') {
//                $('#frmaddress_1_frmemail').val($('#frmusername').val());
//            }

            $('#frmaddress_1_frmemail').val($('#frmpersonalia_1_frmusername').val());

            var form = this.bookingForm.getForm(formPage);
            var res = form.onSubmit();

            if (res) {

                // slide the formcontainer to the right
                var that = this;

                var callback = function() {

                    that.showDialog('Een ogenblik geduld alstublieft.');

                    if ($.browser.msie) {
                        if ($.browser.version != '7.0') {
                            that.clearFilterCallback.apply(this);
                        }
                    }
                }

                if ($.browser.version != '7.0') {
                    $('#formcontainer').hide('drop', {'direction' : 'right', 'easing' : 'easeInBack'}, 'slow', callback);
                } else {
                    callback();
                }

            } else {

                // scroll to top of page to show form errors
                $('html').animate({'scrollTop' : 0}, 200);

            }

//            this.fillCookies();

            return res;

        },

        callMeBack : function() {

            var phone_number = $('#phone-number').val();

            // get the form inputs
            var qs = $('form.bookingform').formSerialize();

            $.post('/?module=DJO&action=MailBookingRequest', qs);

            this.showDialog('<p>Bedankt!</p><p>Uw ingevulde gegevens zijn verstuurd naar Djoser. Wij nemen zo spoedig mogelijk contact met u op.</p>', true);
        },

        initDiscount : function() {

            var that = this;

            // first check if discount-field is in form
            if ($('#frmdiscount_code')) {

                // add validate-button
                var validateButton = $('<div class="button"><a id="validate-button">Bevestig kortingscode</a></div>');
                $('fieldset.discount .element').append(validateButton);

                // bind function to button (and out of field)
//                $('#frmdiscount_code').blur( function() { that.validateDiscountCode(); });
                $('#validate-button').live('click', function() { that.validateDiscountCode(); });

            }

        },

        validateDiscountCode : function() {

            var that = this;

            $('fieldset.discount .element .options').remove();

            var discountCode = $('#frmdiscount_code').val();

            var qs = '&output=json&discountcode=' + discountCode;

            $.each(this.sessionData, function(index, value) {
                qs += '&' + index + '=' + value;
            });

            if (discountCode != '') {

                $.post('/?module=DJO&action=ValidateDiscountCode', qs, function(result) { that.displayBookableDiscounts(result); }, 'json');

            }

        },

        displayBookableDiscounts : function(result) {

            if (result.length != 0) {
                var options = $('<div class="options"></div>');
                var option = $('<div><input type="radio" id="discount_id" class="radio" name="frmdiscount_id" value="" /><label for="discount_id">Geen</label></div>');
                options.append(option);

                for (var a in result) {

                    var option = $('<div><input type="radio" id="discount_id_' + a + '" class="radio" name="frmdiscount_id" value="' + a + '" /><label for="discount_id_' + a + '">' + result[a] + '</label></div>');
                    options.append(option);

                }

                $('fieldset.discount .element').append(options);
            } else {
                var message = $('<div class="options">Er zijn geen kortingen voor deze code</div>');
                $('fieldset.discount .element').append(message);
            }

        },

        /**
         * Loads the interface by setting up elements and loading the url for the first time.
         */
        load : function() {

            var that = this;

            // listen to booking form notifications
            this.bookingForm.bind('formerror', function(form) { that.onFormError(form); });
//            this.bookingForm.bind('login', function() { that.showLoginForm(); return false; });
            this.bookingForm.dataProvider.bind('timeout', function() { that.onTimeout(); });
            this.bookingForm.dataProvider.bind('connectionfail', function() { that.onConnectionFailed(); });

            // append slider
            $('#aside').append('<img id="stepslider" src="/assets/djoser_2010/images/default/booking/arrow_left.png" alt=""/>');

            // create modal
            var opts = {};
            opts.autoOpen = false;
            opts.width = 600;
            opts.modal = true;
            opts.bgiframe = true;
            opts.position = [150, 200];

            $('#dialog').dialog(opts);

            if (that.sessionData.currentpage == 1) {
                that.showLoginForm();
                $('#forgotpassword').bind('click', function(e) { alert('test'); e.preventDefault(); that.showForgotPasswordForm(); });
            }

        },

        /**
         * Shows modal with given text
         *
         * @param {String}  text
         */
        showDialog : function(text, hideSpinner) {

            if (!this.noDialogs) {

                var dialog = $('#dialog');
                var html = '';

                if (!hideSpinner) {
                    html += '<img class="loading" src="/assets/djoser_2010/images/default/booking/loading.gif" alt=""/>';
                }

                html += text;

                dialog.html(html);
                dialog.dialog('open');

            }
        },

        /**
         * Hides modal
         */
        hideDialog : function() {
            $('#dialog').parent().removeClass('iframe-popup');
            $('#dialog').dialog('close');
        },

        clearFilterCallback : function() {
            this.style.removeAttribute('filter');
        }
    }

}();
