jQuery.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    jQuery.each(a, function() {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};


function scrollToTop () {
  var y = 0;
  if (window.pageYOffset) {
    y = window.pageYOffset;
  } else if (document.body && document.body.scrollTop) {
    y = document.body.scrollTop;
  }
  if (y > 0) {
    window.scrollBy(0, -10);
    setTimeout("scrollToTop()", 10);
  }
}


(function() {
    jQuery.gadget.register("calculator", {
        initialize : function() {
            var gadget = this;
            gadget.consumption_coefficient = 0;
            gadget.area_coefficient = 1;
            gadget.climate_factor = 1;
            gadget.energy_consumption = 0;
            gadget.calculator_form = gadget.find("#calculator_form");
            gadget.calculator_form.hide();
            gadget.calculator_results = gadget.find("#calculator_results");
            gadget.calculator_results.hide();
            gadget.result_interpretation = gadget.find("#result_interpretation");
            gadget.firstError;

            gadget.setLanguage();
            if(gadget.urlParams.loadConfiguration) {
                gadget.loadConfig(function() {
                    gadget.setup(gadget);
                });
            } else {
                gadget.setup(gadget);
            }

        },

        setup: function(gadget) {
            gadget.translate(gadget);
            gadget.insertHeatingPeriods(gadget);
            if(gadget.urlParams.enhanceForm) { gadget.enhanceForm(gadget); }
            gadget.observeAreaCalculation(gadget);
            gadget.observeDirectAreaInput(gadget);
            gadget.calculator_results.hide();
            gadget.calculator_form.show();
            gadget.calculateOnSubmit(gadget);
            gadget.attachRecalculateButton(gadget);
            gadget.calculator_form.show();
        },

        translate: function(gadget) {
            for(lang in gadget.settings.labels) {
                if(lang == gadget.lang) {
                    gadget.labels = gadget.settings.labels[gadget.lang]

                    for(var i in gadget.labels) {
                        gadget.find("label:contains('" + i + "'), legend:contains('" + i + "'), .hint:contains('" + i + "'), .label:contains('" + i + "'), .msg:contains('" + i + "'), option:contains('" + i + "'), option[value='" + i + "']").each(function(n, el) {
                            if(jQuery(el).html() == i.toString()) {
                                jQuery(el).html(gadget.labels[i]);
                            };
                        })
                    }

                    gadget.find("input[id='calculate']").val(gadget.labels.calculate);
                }
            }
        },

        insertHeatingPeriods: function(gadget) {
            var sel = gadget.find('select#heating_period');
            for(var i in gadget.getData('heating_periods')) {
                var o = jQuery("<option>").attr('value', i).html(i);
                jQuery(sel).append(o);
            }
        },

        enhanceForm: function(gadget) {
            var people_in_household = gadget.find("#people_in_household").parent('li');
            people_in_household.hide();

            var hot_water_production = gadget.find("input[id *= 'hot_water_production']");
            var hot_water_production_observer = function() {
                if(parseInt(jQuery(this).val()) > 1) {
                  people_in_household.show();
                } else {
                  people_in_household.hide();
                }
            };
            hot_water_production.change(hot_water_production_observer);
            hot_water_production.click(hot_water_production_observer);

            gadget.selectToSlider(gadget, 'heated_floors_count', '');
            gadget.selectToSlider(gadget, 'basement_heating', '');
            gadget.selectToSlider(gadget, 'pavement_heating', '');
            gadget.selectToSlider(gadget, 'heating_period', 2, true);

            var direct_input = jQuery("<div>").html(gadget.find("#insert_area").html());
            direct_input.attr('id', 'insert_directly');
            var direct_input_label = direct_input.children("label");
            var calculate_area = gadget.find("#calculate_area")
            direct_input_label
            .html(
                jQuery("<a>").attr('href', '#')
                .html(direct_input_label.html())
                .click(function() {
                    jQuery(this).parent().nextAll().toggle();
                    jQuery(this).parents("#insert_directly").prevAll(":not('.label')").toggle();
                    if(jQuery(this).parent().css('margin') == '0px 0.5em 0px 0px') {
                        jQuery(this).parent().css('margin', '0 .5em 1em 180px')
                    } else {
                        jQuery(this).parent().css('margin', '0px 0.5em 0px 0px')
                    }
                    return false;
                })
            )
            .css({'margin': '0 .5em 1em 180px', 'width':'auto'})
            direct_input_label.nextAll().hide();
            calculate_area.append(direct_input);
            gadget.find("#insert_area").remove();
        },

        selectToRadio: function(gadget, id, css) {
            if(!css)
            css = '';
            var sel = gadget.find('#' + id);
            var options = jQuery(sel).children();
            var radio_buttons = jQuery("<ol>").addClass('inputs check_boxes ' + css);
            for(var i=0; i<options.length; i++){
                var value = jQuery(options[i]).attr('value');
                var radio_id = id + "_" + value;
                var label = jQuery(options[i]).html();
                var row = jQuery("<li>")
                var radio = jQuery("<input>").attr({'type':'radio', 'value': value, 'name': id, 'id': radio_id });
                if(jQuery(options[i]).attr('selected'))
                radio.attr('checked', 'checked');
                var label = jQuery("<label>").attr('for', radio_id).html(label);
                row.append(radio);
                row.append(label);
                radio_buttons.append(row);
            }
            sel.after(radio_buttons);
            sel.remove();
        },

        selectToSlider: function(gadget, id, labels_count, tooltip) {
            var select = gadget.find('select#' + id);
            if(!labels_count)
              labels_count = select.children().length
            if(!tooltip)
              tooltip = false;
            select.selectToUISlider({labelSrc: 'text', labels: labels_count, tooltip: tooltip});
            var slider = select.next();
            slider.css("width", '300px');
            if(tooltip){
                slider.addClass('slider-with-tooltip');
                select.prevAll('label').addClass('slider-label');
            }
            select.addClass('accessibility-hidden');
            
            slider.focus(function() {
                gadget.setArea(gadget);
            })
        },

        setArea: function(gadget) {
          var fields = jQuery("#calculate_area input#width, #calculate_area input#length");
          var direct_input = gadget.find("input#direct_input");
          var area = gadget.find("input#area");
          var result_display = gadget.find("#result_display");
          var result;
          if(direct_input.val() > 0) {
              result = direct_input.val();
          } else {
              result = jQuery(fields[0]).val()*jQuery(fields[1]).val();
            if(result > 0) {
                result_display.html("<span class='equal'>=</span>" + result + "m<sup>2</sup>");
            }
          }
          area.val(result);
        },

        observeAreaCalculation: function(gadget) {
            var fields = jQuery("#calculate_area input#width, #calculate_area input#length");
            var direct_input = gadget.find("input#direct_input");
            var result_display = gadget.find("#result_display");

            if(result_display.length == 0){
                result_display = jQuery("<strong>").attr('id', 'result_display');
                jQuery(fields[1]).next().after(result_display);
            }

            fields.blur(function() {
                if(jQuery(this).val() == '') jQuery(this).val(0);
                direct_input.val('');
                gadget.setArea(gadget);
            });
        },

        observeDirectAreaInput: function(gadget) {
          var fields = jQuery("#calculate_area input#width, #calculate_area input#length");
          var direct_input = gadget.find("input#direct_input");

          direct_input.blur(function() {
              fields.val('');
              gadget.setArea(gadget);
          });
        },

        calculateOnSubmit: function(gadget) {
            gadget.find("form").submit(function() {
                gadget.setArea(gadget);
                gadget.calculate(gadget);
                return false;
            });
        },

        attachRecalculateButton: function(gadget) {
            gadget.find('a.recalculate').click(function() {
                gadget.calculator_results.hide();
                gadget.calculator_form.show();
                return false;
            });
        },

        validateForm: function(gadget, data) {
            gadget.firstError = '';
            var passed = true;
            gadget.find('.error-msg').remove();
            gadget.find('.error').removeClass('error');
            if(!data.area || data.area == 0 || data.area == '') {
                var fields = gadget.find("#calculate_area");
                fields.addClass('error');
                fields.parent().before(gadget.errorMessage(gadget.labels.error_area));
                gadget.firstError = gadget.calculator_form.find('input#length');
                passed = false;
            }

            if(!data.annual_consumption || data.annual_consumption == 0 || data.annual_consumption == '') {
                var fields = gadget.find("#annual_consumption");
                fields.parent('li').addClass('error');
                fields.parents('fieldset').children('.inputs').before(gadget.errorMessage(gadget.labels.error_annual_consumption));
                if(!gadget.firstError) {
                    gadget.firstError = fields;
                }

                passed = false;
            }

            if(data.hot_water_production > 1 && (!data.people_in_household || data.people_in_household == 0 || data.people_in_household == '')) {
                var fields = gadget.find("#people_in_household");
                fields.parent('li').addClass('error')
                fields.after(gadget.errorMessage(gadget.labels.error_people_in_household, 'inline-error-msg'));
                if(!gadget.firstError) {
                    gadget.firstError = fields;
                }
                passed = false;
            }

            return passed;
        },

        errorMessage: function(msg, cssClass) {
            css = 'error-msg'
            if(cssClass)
              css = 'error-msg ' + cssClass;
            return jQuery("<p class='" + css + "'>").html(msg);
        },

        calculate: function(gadget) {
            var f = jQuery("form input, form select");
            var data = jQuery(f).serializeObject();

            function insertSimpleValues() {
                for(var i in data) {
                    if(data[i] != "") {
                        //insert value (eg: 2008) in placeholder with corresponding css-class (eg, 'heating_period')
                        var val = data[i];

                        // if the value was chosen from a predefined answer (select field, radio, etc.)
                        // look it up in the labels instead (combination of key + value, eg: 'building_type_1', 'basement_heating_3')
                        var combined_key = i + "_" + data[i];
                        var combined_val = '';
                        if(combined_key)
                            if(gadget.labels[combined_key])
                                combined_val = gadget.labels[combined_key];
                        if(combined_val != '')
                            val = combined_val;

                        gadget.calculator_results.find("." + i).html(val);
                    }
                }
            }

            function calculateEnergyConsumption() {
                // consumption = Annual Consumption * Energy Factor
                gadget.consumption_coefficient = function() {
                    return parseFloat(data.annual_consumption) * gadget.settings.energy_factors[data.energy_source];
                }();

                gadget.consumption_reduction = function() {
                  var reduction = 0;
                  if(data.hot_water_production == 2)
                    reduction = data.people_in_household * 1000;
                  if(data.hot_water_production == 3)
                    reduction = data.people_in_household * 500;
                  return reduction;
                }();


                gadget.area_coefficient = function() {

                    function basement_pavement(val) {
                        switch(val){
                            case '1':
                                return 0.25;
                            case '2':
                                return 0.5;
                            case '3':
                                return 0.75;
                            default:
                                return 0;
                        }

                    }

                    var basement = basement_pavement(data.basement_heating);
                    var pavement = basement_pavement(data.pavement_heating);
                    var total = parseFloat(data.area*data.heated_floors_count + data.area*basement + data.area*pavement);

                    if(total > 0) {
                        return total;
                    } else {
                        return 1;
                    }
                }();

                gadget.climate_factor = gadget.getData('heating_periods')[data.heating_period];
                gadget.energy_consumption = (gadget.consumption_coefficient - gadget.consumption_reduction)/(gadget.area_coefficient/gadget.climate_factor);
            }

            function interpretResult() {
                var r = '';
                if(gadget.energy_consumption < 43)
                    r = 'a';
                if(gadget.energy_consumption >  42 && gadget.energy_consumption < 61)
                    r = 'b';
                if(gadget.energy_consumption >  60 && gadget.energy_consumption < 81)
                    r = 'c';
                if(gadget.energy_consumption >  80 && gadget.energy_consumption < 111)
                    r = 'd';
                if(gadget.energy_consumption >  110 && gadget.energy_consumption < 151)
                    r = 'e';
                if(gadget.energy_consumption >  150 && gadget.energy_consumption < 201)
                    r = 'f';
                if(gadget.energy_consumption >  200)
                    r = 'g';

                gadget.result_interpretation.html('');
                var img = gadget.urlParams.approot + '/img/rechner_' + r.toUpperCase() + ".gif";
                var energy_consumption = jQuery("<p>")
                    .append(jQuery("<span>").html(gadget.labels.energy_consumption))
                    .append("&nbsp;")
                    .append(jQuery("<strong>").html(Math.floor(gadget.energy_consumption)))
                var title = jQuery("<h3>").html(gadget.labels.result_title);

                var msg = jQuery("<p>").append(gadget.labels['message_' + r]);
                msg.find("a.contact-url").attr('href', gadget.urlParams.contactUrl);
                gadget.result_interpretation.append(jQuery("<img>").attr('src', img));
                gadget.result_interpretation.append(energy_consumption);
                gadget.result_interpretation.append(title);
                gadget.result_interpretation.append(msg);
            }


            function togglePeopleInHouseHold() {
              // Show people_in_household only if it matters (-> hot_water_production > 1)
              var people_in_household = gadget.calculator_results.find('.people_in_household');
              if(gadget.consumption_reduction > 0) {
                people_in_household.prev().show();
                people_in_household.show();
              } else {
                people_in_household.prev().hide();
                people_in_household.hide();
              }
            }


            if(gadget.validateForm(gadget, data)) {
                insertSimpleValues();
                calculateEnergyConsumption();
                interpretResult();
                togglePeopleInHouseHold();
                gadget.calculator_form.hide();
                gadget.calculator_results.show();
                scrollToTop();
            } else {
                gadget.firstError.focus();
            }

        }
    });
})();