/* Forms plugin
------------------------------------------------------------------------------------------------ */

(function($) {
    $.fn.forms = function(settings) {

        if (!this.length) return;

        settings = $.extend({
            'confirmpage'       : 'html',       // Values: html | ajax | iframe (ajax is broken at the moment!)
            'error_value'       : false,        // Error message as input value
            'infobox'           : '.info',      // Container class for progress steps etc.
            'multipage'         : true,         // Multipage
            'scrolltop'         : '#content',   // Scrolltop ID for next/previous page
            'summarypage'       : true,         // Summarypage (only with active multipage)
            'progress_steps'    : true,         // Progress steps
            'debug'             : false         // Debug mode
        }, settings);

        return this.each(function() {

            var form = this;
            var paramName;
           

            // Turn off autocomplete with javascript. It's not a valid HTML4 attribut!

            if(settings.error_value)
                $(form).attr('autocomplete', 'off');

            // Disclaimer
            $.fn.forms.disclaimer(form);

            // Multiple inputs
            $.fn.forms.multiInput(form);

            // Multipage
            $.fn.forms.multipage(form, settings);

            // Update contactinfo
            $.fn.forms.updateReceiver(form);

            // Error in value
            $.fn.forms.valueErrorMsg(form, settings);

            // Dependence
            $.fn.forms.dependence(form, settings);

            // URL Parameters
            $.fn.forms.urlParameters(form);         
            
            // Live validation on blur
            $.fn.forms.validcheck(form, settings, 'live');

            // Validate on submit

            $(form).submit(function() {

                if (settings.confirmpage == 'iframe') {

                    $('#iframesubmit').remove();

                    $(form).attr({
                        'target'    : 'iframesubmit'
                    });

                    $('body').append(
                        $('<iframe name="iframesubmit">').attr({    // IE Fix: Add the name with attr() don't work -> Iframe open in a new window
                            'class' : 'iframesubmit',
                            'id'    : 'iframesubmit'
                        })
                    );

                    if (!settings.debug) {
                        $('.iframesubmit').addClass('hideme');
                    }

                }

                // Focus first input

                setTimeout(function() {
                    $('.error :input:enabled:first', form).focus();
                }, 300);

                // Validate form

                var valid = $.fn.forms.validcheck(form, settings);
                return valid ? $.fn.forms.confirm(form, settings) : false;
            });
        });
    }

    // Validate form

    $.fn.forms.valid = function (el, settings, check) {

        var valid       = true,
            error_msg   = '';

        switch (el.type) {

            case 'radio':

                // radio validation

                valid       = false;
                error_msg   = 'Treffen Sie mindestens eine Auswahl!';

                $('input[name='+el.name+']').each(function() {
                    if ($(this).is(':checked')) {
                        error_msg   = '';
                        valid       = true;
                    }
                });

                break;

            case 'checkbox':

                // checkbox validation

                var siblings = $(el).siblings('.group').andSelf();

                if (siblings.length > 1) {
                    $(el).parents('.entry').find('.group:last').addClass('last');
                    if (check == 'live' && $(el).hasClass('last') ||
                        check == 'live' && !$(el).hasClass('last') && $(el).parents('.entry').hasClass('error') ||
                        check != 'live') {
                        if(!$(siblings).is(':checked')){
                            error_msg   = error_msg_checkbox;
                            valid       = false;
                        }
                    }
                }
                else {
                    if (!$(el).is(':checked')) {
                        error_msg   = error_msg_checkbox;
                        valid       = false;
                    }
                }
                break;

            default:

                // Normal validation

                if (el.value == '' || el.value == error_msg_default) {

                    error_msg   = error_msg_default;
                    valid       = false;

                }

                // Email validation

                else if ($(el).hasClass('email')) {

                    var regExp = /^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;

                    if (!el.value.match(regExp)) {

                        error_msg   = error_msg_email;
                        valid       = false;
                    }

                }

                // Numbers validation

                else if ($(el).hasClass('number')) {

                    if (el.value != Math.round(el.value)) {

                        error_msg   = error_msg_number;
                        valid       = false;

                    }

                }

                // Url validation
                
                else if ($(el).hasClass('url')) {

                    var regExp = /(http|https|ftp)?:\/\//;

                    if (el.value.match(regExp)) {

                        error_msg   = 'Links sind nicht erlaubt!';
                        valid       = false;
                    }
                }
        }

        // Error message

        if (valid) {

            // Remove error message

            $('.error_msg', $(el).parents('.entry')).remove();
            
            // Add okay class and remove error class

            $(el).parents('.entry').addClass('okay');
            $(el).parents('.entry').removeClass('error');

        }
        else {

            // custom error message

            if(custom_required_text[el.id])
                error_msg = custom_required_text[el.id];

            // insert error message

            if (!$(el).parents('.entry').hasClass('error')) {

                var error_msg_box = $('<p>').addClass('error_msg').hide().text(error_msg);

                switch (el.type) {

                    case 'radio':

                        error_msg_box.insertBefore($('input[name='+el.name+']:first'));
                        break;

                    case 'checkbox':

                        if ($(el).hasClass('group'))
                            error_msg_box.insertBefore($(el).parents('.entry').find('.group:first'));
                        else
                            error_msg_box.insertBefore($(el));
                        break;

                    default:

                        if (settings.error_value && el.type != 'select-one' && $(el).is(':visible')) {
                            $(el).data('value', $(el).val());
                            $(el).addClass('error_value');
                            $(el).val(error_msg);
                        }
                        else if ($(el).siblings('.datepicker').length)
                            error_msg_box.insertAfter($(el).siblings('.datepicker'));
                        else
                            error_msg_box.insertAfter($(el));
                }

                error_msg_box.fadeIn();
            }
            else {

                // Insert error message

                $('.error_msg', $(el).parents('.entry')).text(error_msg);

            }

            // Add error class and remove okay class

            $(el).parents('.entry').addClass('error');
            $(el).parents('.entry').removeClass('okay');
        }
    }

    // Live, multipage or normal validation check

    $.fn.forms.validcheck = function(form, settings, check) {

        var toValidate = new Array();

        switch (check) {

            case 'live':
                $('.required', form).blur(function() {

                    toValidate.push(this);

                    setTimeout(function() {
                        if (toValidate.length > 0) {
                            if ($(toValidate[0]).hasClass('required')) { // Some "required" classes might have been removed in the meantime (see dependencies)
                                $.fn.forms.valid(toValidate[0], settings, 'live');
                            }
                            toValidate.shift();
                        }
                    }, 300);

                });
                break;

            default:
                var required = (check == 'multipage') ? $('.section:visible .required', form) : $('.required', form);
                required.each(function() {
                    $.fn.forms.valid(this, settings);
                });

        }

        return ($('.error', form).length || $('.error_value:visible', form).length) ? false : true;

    }

    // Error in value

    $.fn.forms.valueErrorMsg = function(form, settings) {

        if (!settings.error_value)
            return;

        $('.required', form).focus(function() {
            if ($(this).hasClass('error_value')) {
                $(this).val($(this).data('value')).data('value', '').removeClass('error_value');
                $(this).parents('.error').removeClass('error');
            }
        });
    }

    // Get input value

    $.fn.forms.value = function(el) {

        var value = '';

        if ($(el).is('select')) {
            value = $(':selected', el).text();
        }
        else if ($(el).is('input[type=checkbox]') && $(el).is(':checked')) {
            value = yes;
        }
        else if ($(el).is('input[type=checkbox]') && !$(el).is(':checked')) {
            value = no;
        }
        else {
            value = $(el).val();
        }

        return value;
    }

    // Dependence

    $.fn.forms.dependence = function(form, settings) {

        // Check radio

        $('input[type=radio]', form).click(function() {

            var el = this;

            $('input[name='+el.name+']').each(function() {
                if ($(this).is(':checked') && $(this).hasClass('dependence')) {
                    addRequired(this);
                }
                else if (!$(this).is(':checked') && $(this).hasClass('dependence')) {
                    removeRequired(this);
                }
            });

            $.fn.forms.validcheck(form, settings, 'live');
        });

        // Check checkbox, textarea and input[type=text]

        $('.dependence', form).not('input[type=radio]').blur(function() {

            var el = this;

            switch(el.type) {

                case 'checkbox':
                    alert("not available at the moment");
                    break;

                default:
                    (el.value.length) ? addRequired(el) : removeRequired(el);

            }
            $.fn.forms.validcheck(form, settings, 'live');
        });

        // Add required

        function addRequired(el) {

            $('.depends_on_' + el.id).each(function() {

                $(this).addClass('required');
                var label = 'label[for='+this.id+']';

                if (!$(label).find('em').length) {
                    $(label).append(
                        $('<em>').addClass('required_asterisk').text(' *')
                    );
                }
            });

        }

        // Remove required

        function removeRequired(el) {

            $('.depends_on_' + el.id).each(function(){
                $(this).removeClass('required');
                $(this).unbind();
                $(this).parents('.entry').removeClass('error');
                $('.error_msg', $(this).parents('.entry')).remove();
                $('label[for='+this.id+'] em').remove();
            });

        }
    }

    // Create multipage, summarypage and progress bar

    $.fn.forms.multipage = function(form, settings) {

        if(!settings.multipage)
            return;

        // Generate the progress bar and steps

        if (settings.progress_steps) {

            var progress_steps = $('<h2>').attr({
                'id' : 'progress_steps'
            });
            progress_steps.appendTo($(settings.infobox));

        }

        var progress_bar = $('<ol>').attr({
            'class'     : 'clearfix',
            'id'        : 'progress_bar'
        });

        $('.section_title', form).each(function(index) {
            $('<li>').text($(this).text()).addClass('progress_' + index).appendTo(progress_bar);
        })

        if (settings.summarypage) {

            $('.section:last', form).after(
                summary_section = $('<div>').addClass('section summary_section')
            );
            $('<li>').text(summary_title).addClass('last').appendTo(progress_bar);

        }

        progress_bar.appendTo($(settings.infobox));

        // Show only first section

        $('.section', form).show().not(':first').hide();

        // Back button

        $('<button type=button>').attr({
            'accesskey'     : 'b',
            'name'          : 'back'
            }).html('<span>' + back + '</span>').click(function() {

                $('.section:visible', form).hide().prev().show();
                $(':input:enabled:first', form).focus();
                $('#errorpage').remove();

                $.fn.forms.multipage.update(form, settings, progress_bar, progress_steps);

                // Jump to top of the form

                $('html, body').scrollTop($(settings.scrolltop).offset().top - 10);

                // Hide required text on summary page

                summary_section.is(':visible') ? $('.required_text', settings.infobox).hide() : $('.required_text', settings.infobox).show();

                return false;

        }).insertBefore('button[name=send]', form).hide();

        // Next button

        $('<button type=button>').attr({
            'accesskey'     : 'n',
            'name'          : 'next'
            }).html('<span>' + next + '</span>').click(function() {

                $.fn.forms.validcheck(form, settings, 'multipage');

                if (!$('.error:visible', form).length &&
                    !$('.error_value:visible', form).length) {

                    $('.section:visible', form).hide().next().show();
                    $('.section:visible :input:enabled:first', form).focus();

                    // Generate summary

                    $.fn.forms.summarypage(form, settings);

                    $.fn.forms.multipage.update(form, settings, progress_bar, progress_steps);

                    // Jump to top of the form

                    $('html, body').scrollTop($(settings.scrolltop).offset().top-10);

                    // Hide required text on summary page

                    summary_section.is(':visible') ? $('.required_text', settings.infobox).hide() : $('.required_text', settings.infobox).show();

                }
                else {

                    if(!settings.error_value)
                        $('.error :input:enabled:first', form).focus();

                }

            return false;

        }).insertBefore('button[name=send]', form).hide();

        $.fn.forms.multipage.update(form, settings, progress_bar, progress_steps);
    }

    // Should be run in each formfield change handles progress bar navigation and buttons

    $.fn.forms.multipage.update = function(form, settings, progress_bar, progress_steps) {

        // Update button next

        var button_back = $('button[name=back]', form);
        $('.section:first:visible', form).is(':visible') ? button_back.hide() : button_back.show();

        // Update button last

        var button_next = $('button[name=next]', form);
        $('.section:last', form).is(':visible') ? button_next.hide() : button_next.show();

        // Update button submit

        var button_submit = $('button[name=send]', form);
        !$('.section:last', form).is(':visible') ? button_submit.attr({ 'disabled': 'true' }).hide() : button_submit.attr({ 'disabled': '' }).show();

        // Update progress bar

        $('li', progress_bar).removeClass('active');

        $('li:contains("'+$('.section:visible .section_title', form).text()+'")', progress_bar).addClass('active done');

        $('li', progress_bar).each(function(index) {
            var title = $(this).text();
            if (!$(this).children('a').length &&
                $(this).hasClass('done')) {
                $(this).wrapInner(
                    $('<a>').attr({ 'rel': index, 'href': '#', 'title': title })
                );
            }
        });

        $('a', progress_bar).bind('click', function() {

            $('.section:visible', form).hide();
            $('.section:eq('+this.rel+')', form).show();
            $(':input:visible:enabled:first', form).focus();

            // Hide required text on summary page

            summary_section.is(':visible') ? $('.required_text', settings.infobox).hide() : $('.required_text', settings.infobox).show();

            $.fn.forms.multipage.update(form);
            return false;
        });

        // Update progress steps

        if (settings.progress_steps) {
            $(progress_steps).html(
                progress_step.replace('{x}', $('li.active', progress_bar).prevAll().length + 1).replace('{y}', $('li', progress_bar).length)
            );
        }

    };

    // Generate summary table

    $.fn.forms.summarypage = function(form, settings) {

        if (settings.summarypage &&
            $('.section:last', form).is(':visible')) {

            $('.summary_section', form).empty().append(
                $('<h2>').addClass('section_title').attr('title', 'summary_title').text(summary_title)
            );

            $('.section', form).not(':last').each(function() {

                var section_title = $('.section_title', this).text();

                $('<table>').addClass('summary').append(
                    $('<caption>').html(section_title),
                    tbody = $('<tbody>')
                ).appendTo(summary_section);

                $('label', $(this)).each(function() {

                    var me = $(this).parents('.multi_entry');

                    if (me.length) {

                        if ($(this).hasClass('hideme')) {

                            $(tbody).append(
                                $('<tr>').append(
                                    $('<td class="multi_summary" colspan="2">').append(
                                        subtable = $('<table>').append(
                                            $('<thead>').append($('<tr>')),
                                            $('<tbody>')
                                        )
                                    )
                                )
                            );

                            $('.entry:first label', me).each(function() {
                                $('thead tr', subtable).append($('<th>').text($(this).text().replace(' *', '')));
                            });

                            $('.entry', me).each(function() {
                                var row = $('<tr>');
                                $(':input', this).each(function(){
                                    var value = $.fn.forms.value(this);
                                    row.append($('<td>').text(value));
                                });
                                $('tbody', subtable).append(row);
                            });
                        }

                    }
                    else {

                        var value = $.fn.forms.value('#'+$(this).attr('for'));

                        if (value.length) {
                            $(tbody).append(
                                $('<tr>').append(
                                    $('<th>').text($(this).text().replace(' *', '')),
                                    $('<td>').text(value)
                                )
                            );
                        }

                    }
                });
            });
        }
    };

    // Update contactinfos on change email receiver

    $.fn.forms.updateReceiver = function(form) {

        $('#secure_target', form).change(function() {

            var contactID = $(':selected', $(this)).attr('id');

            if (contactID.length) {
                $('.locations_data .' + contactID + ' span', form).each(function() {
                    $('input[name=to_' + $(this).attr('title') + ']').val($(this).text());
                });
            }

        });
    }

    //Multiple Inputs init

    $.fn.forms.multiInput = function(form) {

        $('.multi_entry', form).each(function(i) {

            var me      = this,
                meid    = $('.multi_title', me).attr('id') + '_multi';

            $(me).append(

                $('<p>').html(
                    $('<a>').attr({
                        'href'  : '#'
                    }).text(add_entry).click(function() {

                        count = '_' + $('.entry', me).length;
                        clonekrieger = $('.entry:first', me).clone();
                        clonekrieger.addClass('clone');

                        $('label', clonekrieger).each(function() {
                            $(this).attr({
                                'for'       : $(this).attr('for') + count
                            });
                        });

                        $(':input', clonekrieger).each(function() {
                            $(this).attr({
                                'id'        : $(this).attr('id') + count,
                                'name'      : $(this).attr('name')+count
                            }).val('');
                        });

                        clonekrieger.insertBefore($(this).parent());
                        $.fn.forms.multiInput.update(me);
                        return false;

                    })
                ).addClass('add'),

                $('<input>').attr({
                    'type'      : 'hidden',
                    'name'      : meid,
                    'id'        : meid
                }),
                $('<label>').attr({
                    'for'       : meid
                }).html($('legend', this).html()).addClass('hideme')

            );
            $.fn.forms.multiInput.update(me);
        });

    }

    //Update on Unfocus

    $.fn.forms.multiInput.update = function(me) {

        $(':input', me).unbind().blur(function() {

            var v = '';

            $('.entry :input', me).each(function() {
                v += $('label[for=' + $(this).attr('id') + ']').text().replace(' *', '') + ': ';
                v += $.fn.forms.value(this) + '\n';
            })

            $('input[name=' + $('legend', me).attr('id') + '_multi]', me).val(v);
        });

    };

    // Send message and load confirm text with ajax

    $.fn.forms.confirm = function(form, settings) {

        // Debug mode
        
        if (settings.debug) {
            console.log('settings.confirmpage: ' + settings.confirmpage);
        }

        // Disable send button

        $('button[name=send] span', form).text(wait).attr('disabled', 'disabled');

        // Send message and load confirmpage with ajax

        if (settings.confirmpage == 'ajax') {

            // Debug mode
            
            if (settings.debug) {
                console.log('Action: ' + $(form).attr('action'));
                console.log('Data: ' + $(form).serialize());
            }

            $.ajax({
                'type'      : 'POST',
                'url'       : $(form).attr('action'),
                'data'      : $(form).serialize(),
                'cache'     : true,
                'complete'  : function(data, textStatus) {

                                // Insert confirmpage

                                $('.required_text').remove();

                                $(form).after(
                                    $('<div>').attr({
                                        'id'    : 'confirmpage'
                                    }).load($('input[name=next]').val() + ' #confirm')
                                );

                                $(form).remove();

                                // Show summary page
    
                                if (settings.summarypage && settings.multipage) {

                                    $('#confirmpage').after(
                                        $('<p>').addClass('print').append(
                                            $('<a>').attr({
                                                'href'      : '#',
                                                'title'     : 'Zusammenfassung drucken'
                                            }).text('Zusammenfassung drucken')
                                        ),
                                        summary_section.clone()
                                    );

                                    $('.print').click(function() {
                                        window.print();
                                        return false;
                                    });

                                }

                                // Scroll to the top

                                $('html, body').scrollTop($(settings.scrolltop).offset().top - 10);

                                // Debug mode

                                if (settings.debug) {
                                    console.log('Ajax complete.');
                                    console.log('Data: '    + data);
                                    console.log('Status: '  + textStatus);
                                }

                                return false;
                            }
            });
        }

        // Send message with hidden iframe

        else if (settings.confirmpage == 'iframe') {

            // Insert confirmpage

            $('#iframesubmit').load(function(responseText, textStatus, XMLHttpRequest) {

                try {

                    var confirm = $('.iframesubmit').contents().find('#confirm').html();

                    // Remove form and insert confirmpage

                    $(form).after(
                        $('<div>').attr({
                            'id'        : 'confirmpage'
                            }).append(confirm)
                    );

                    $('#errorpage').remove();

                }

                catch (e) {

                    if (!$('#errorpage').length) {

                        $(form).before(
                            $('<div>').attr({
                                'id'    : 'errorpage'
                            }).append(
                                $('<h2>').text(errorpage_headline),
                                $('<p>').text(errorpage)
                            )
                        )

                    }

                }

                if (!$('#errorpage').length) {

                    $('.required_text').remove();
                    $(form).remove();

                    // Show summary page

                    if (settings.summarypage &&
                        settings.multipage) {

                        $('#confirmpage').after(
                            $('<p>').addClass('print').append(
                                $('<a>').attr({
                                    'href'      : '#',
                                    'title'     : 'Zusammenfassung drucken'
                                }).text('Zusammenfassung drucken')
                            ),
                            summary_section.clone()
                        );

                        $('.print').click(function() {
                            window.print();
                            return false;
                        });
                    }
                    
                    // Remove progessbar links
                    
                    $('#progress_bar li').each(function() {
                        var text = $('a', this).text();
                        
                        $('a', this).remove();
                        $(this).text(text);
                    });

                }
                else {
                    $('button[name=send] span', form).text(send).attr('disable', '');
                }

                // Scroll to the top

                $('html, body').scrollTop($(settings.scrolltop).offset().top - 10);

            });
            return true;
        }

        // Normal send

        else if (settings.confirmpage == 'html') {
            return true;
        }
    }

    // Show and hide the disclaimer

    $.fn.forms.disclaimer = function(form) {

        var disclaimer          = $('#disclaimer', form),
            show_disclaimer     = $('#show_disclaimer', form);

        if (!disclaimer.length && !show_disclaimer.length)
            return;

        disclaimer.hide();
        
        show_disclaimer.click(function (){

            disclaimer.slideToggle('slow');
            return false;

        });

    }
  
    // Get url parameters and add as hidden input

    $.fn.forms.urlParameters = function(form) {

        var href = window.location.href;

        if (href.indexOf('?') < 0)
            return;

        var parameters = href.split('?')[1].split('&');

        for (x = 0; x < parameters.length; x ++) {

            var parameter    = parameters[x].split('=')[0],
                value        = parameters[x].split('=')[1];
                value        = decodeURI(value);

            if ($('input[name = ' + parameter + ']', form).length) {
                $('input[name = ' + parameter + ']', form).attr('value', value);
            }
            else {
                $(form).prepend(
                    $('<input>').attr({
                        'name'  : parameter,
                        'type'  : 'hidden',
                        'value' : value
                    })
                );
            }
        }
    };

})(jQuery);
