function compact(array) {
    var new_array = [];
    for (var i = 0; i < array.length; i++) {
        if ( array[i] ) new_array.push(array[i]);
    }
    return new_array;
}

if ((typeof InSales) == 'undefined') {
    var InSales = {};
}

InSales.isDefined = function(obj) {
  return ((typeof obj == 'undefined') ? false : true);
};

InSales.money_format = "{{amount}} руб.";

InSales.formatMoney = function(amount, format) {
    if (amount == null) return '';
    var value = '';
    var patt = /\{\{\s*(\w+)\s*\}\}/;
    var formatString = (format || this.money_format);
    switch(formatString.match(patt)[1]) {
        case 'amount':
            value = floatToString(amount, 2);
            break;
        case 'amount_no_decimals':
            value = floatToString(amount, 0);
            break;
	case 'amount_with_comma_separator':
            value = floatToString(amount, 2).replace(/\./, ',');
            break;
    }
    // формат вывода должен совпадать форматом вывода в Liquid
    value = floatToString(amount, 2).replace(/,00/, '').replace(/\.00/, '');
    return formatString.replace(patt, value);
};

function floatToString(numeric, decimals) {
    numeric = numeric || 0;
    var amount = numeric.toFixed(decimals).toString();  
    if(amount.match(/^\.\d+/)) {return "0"+amount; }
    else { return amount; }
};

InSales.Product = function(json) {

    // Вспомогательные методы используемые при инициализации
    this.addOption = function(option) {
        this.options_by_id[option['id']] = {
            title: option['title'],
            values: []
        };
    };

    this.addVariant = function(variant) {
        var option_values = variant['option_values'];
        for (var value in option_values) { this.addValue(option_values[value]); };
    };

    this.addValue = function(value) {
        var option = this.options_by_id[value['option_name_id']];
        option['values'][value['position']] = value['title'];
    };

    // Инициализация
    this.init = function(json) {
        for (property in json) { this[property] = json[property]; }
        this.options_by_id = {};
        for (var option  in this.option_names) { this.addOption(this.option_names[option]); }
        for (var variant in this.variants)  { this.addVariant(this.variants[variant]); };
        jQuery.each(this.options_by_id, function(index,option) { option['values'] = compact(option['values']); });
        
    };

    // returns array of option names for product
    this.optionNames = function() {
        return this.option_names;
    };

    // returns array of all option values (in order) for a given option name index
    this.optionValues = function(index) {
        var option = this.option_names[index];
        if (!option) { return null; }
        return this.options_by_id[option['id']]['values'];
    };

    // return the variant object if exists with given values, otherwise return null
    this.getVariant = function(selectedValues) {
        for (var i in this.variants) {
            var variant = this.variants[i];
            var satisfied = true;
            jQuery.each(variant['option_values'], function(index,value) {
                if (selectedValues[value['option_name_id']] != value['title']) {
                    satisfied = false;
                }
            });
            if (satisfied == true) { return variant; }
        }
        return null;
    };

    this.init(json);
};

InSales.OptionSelectors = function(existingSelectorId, options) {
    if ($("#"+existingSelectorId).attr("id") == undefined) return false

    // insert new multi-selectors and hide original selector
    this.replaceSelector = function(domId) {
        var oldSelector = document.getElementById(domId);
        var parent = oldSelector.parentNode;
        jQuery.each(this.buildSelectors(), function(index,el) {
            parent.insertBefore(el, oldSelector);
        });
        oldSelector.style.display = 'none';
        this.variantIdField = oldSelector;
    };

    // buildSelectors(index)
    // create and return new selector element for given option
    this.buildSelectors = function() {
        // build selectors
        for (var i = 0; i < this.product.optionNames().length; i++) {
            var sel = new InSales.SingleOptionSelector(this, i, this.product.optionNames()[i], this.product.optionValues(i));
            sel.element.disabled = false;
            this.selectors.push(sel);
        }
        
        // replace existing selector with new selectors, new hidden input field, new hidden messageElement
        var divClass = this.selectorDivClass;
        var optionNames = this.product.optionNames();
        var elements = [];
        jQuery.each(this.selectors, function(index,selector) {
            var div = document.createElement('div');
            div.setAttribute('class', divClass);
            // create label if more than 1 option (ie: more than one drop down)
            if (optionNames.length > 1 || optionNames[0].title != 'Модификация') {
                // create and appened a label into div
                var label = document.createElement('label');
                label.innerHTML = selector.name;
                div.appendChild(label);
            } 
            div.appendChild(selector.element);
            elements.push(div);
        });
        return elements;
    };
    
    // returns array of currently selected values from all multiselectors
    this.selectedValues = function() {
        var currValues = {};
        for (var i = 0; i < this.selectors.length; i++) {
            var selector = this.selectors[i]
            var thisValue = selector.element.value;
            currValues[selector.option_id] = thisValue;
        }
        return currValues;
    };
    
    // callback when a selector is updated.
    this.updateSelectors = function(index) {
        var currValues = this.selectedValues(); // get current values
        var variant    = this.product.getVariant(currValues);
        if (variant) {
            this.variantIdField.disabled = false;
            this.variantIdField.value = variant.id; // update hidden selector with new variant id
        } else {
            this.variantIdField.disabled = true;
        }
        this.onVariantSelected(variant, this);  // callback 
    };

    this.selectAvailableVariant = function() {
        var values = {};
        for (var i = 0; i < this.product.variants.length; i++) {
            var variant = this.product.variants[i];
            if (!variant.available) continue;
            jQuery.each(variant.option_values, function(index,option_value) {
                values[option_value.option_name_id] = option_value.title;
            });
            break;
        }
        jQuery.each(this.selectors, function(index,selector) {
            selector.selectValue(values[selector.option_id]);
        });
        this.selectors[0].element.onchange();     // init the new dropdown
    };

    this.selectorDivClass       = 'selector-wrapper';
    this.selectorClass          = 'single-option-selector';
    this.variantIdFieldIdSuffix = '-variant-id';
    
    this.variantIdField    = null;
    this.selectors         = [];
    this.domIdPrefix       = existingSelectorId;
    this.product           = new InSales.Product(options['product']);
    
    this.onVariantSelected = InSales.isDefined(options.onVariantSelected) ? options.onVariantSelected : function(){};
    
    this.replaceSelector(existingSelectorId); // create the dropdowns

    this.selectAvailableVariant();

    return true;  
};


InSales.SingleOptionSelector = function(multiSelector, index, option, values) {
    this.selectValue = function(value) {
        $(this.element).find('option[value='+value+']').each(function(){
            $(this).attr("selected","selected")
        });
    };

    this.multiSelector = multiSelector;
    this.values = values;
    this.index = index;
    this.name = option['title'];
    this.option_id = option['id'];
    this.element = document.createElement('select');
    for (var i = 0; i < values.length; i++) {
        var opt = document.createElement('option');
        opt.value = values[i];
        opt.innerHTML = values[i];
        this.element.appendChild(opt);
    }
    this.element.setAttribute('class', this.multiSelector.selectorClass);
    this.element.id = multiSelector.domIdPrefix + '-option-' + index;
    this.element.onchange = function() {
        multiSelector.updateSelectors(index);
    };

    return true;
};

// Инициализировать добавление товара в корзину через Ajax.
function initAjaxAddToCartButton(handle, onAddToCart) {
    jQuery(handle).click(function(e){
        e.preventDefault();
        addOrderItem( jQuery(this).parents("form:first"), onAddToCart);
    });
}

// Добавление товара в корзину
function addOrderItem(form, onAddToCart) {
    var fields = form.serialize();
    var action = form.attr("action").split("?");
    var url    = action[0] + ".json";
    var lang   = action[1] ? "?"+action[1] : "";
    var path   = url + lang;
    show_preloader(); // Показываем прелоадер
    jQuery.ajax({
        url:      path,
        type:     'post',
        data:     fields,
        dataType: 'json',
        success:  onAddToCart,
        error:    hide_preloader
    });
}

// сабмит формы отзыва
jQuery(function($) {

    $("#feedback_commit").click(function(e){
        e.preventDefault();
        var form = $('#feedback_form');
        var fields = form.serialize();
        $.ajax({
            url:      form.attr('action') + '.json',
            type:     'post',
            data:     fields,
            dataType: 'json',
            beforeSend: function() { show_preloader(); },
            complete: function() { hide_preloader(); },
            success:  function(response) {
                if ( response.status == 'ok' ) {
                    $("textarea[name='feedback[content]']").val("");
                    var thanks = $("#thanks");
                    thanks.html(response.notice);
                    thanks.show();
                    window.setTimeout(function() {
                       thanks.fadeOut("slow", function(){thanks.hide();});
                    }, 3000);
                } else {
                    alert(errors_to_arr(response.errors).join("\n"));
                }
            }
        });
    });

})

// функция вытаскивает сообщения об ошибке из хэша в массив.
function errors_to_arr(errors){
    arr = [];
    $.each( errors, function(obj, msg){
        arr.push(msg);
    });
    return arr;
}


// Вывести индикатор работы (колесико)
function show_preloader() {
    var preloader = jQuery("#own_preloader");
    if ( !preloader.attr("id") ) {
        jQuery("body").append('<div id="own_preloader"><img src="/images/loading.gif"/></div>');
        preloader = jQuery("#own_preloader");
    }
    preloader.show();
    
    changeCss(preloader);
    jQuery(window).bind("resize", function(){
        changeCss(preloader);
    });
    jQuery(window).bind("scroll", function(){
        changeCss(preloader);
    });
}

// Скрыть индикатор
function hide_preloader() {
    var preloader = jQuery("#own_preloader");
    if ( !preloader.attr("id") ) return;
    jQuery(window).unbind("resize");
    jQuery(window).unbind("scroll");
    preloader.remove(); 
}

// Заменить индикатор на сообщение
function set_preloaders_message(message) {
    var preloader = jQuery("#own_preloader");
    if ( !preloader.attr("id") ) return;
    preloader.html(message);
}

function changeCss(OBJ){
    var imageHeight  = OBJ.height();
    var imageWidth   = OBJ.width();
    var windowWidth  = jQuery(window).width();
    var windowHeight = jQuery(window).height();
    OBJ.css({
        "position" : "absolute",
        "left" : windowWidth / 2 - imageWidth / 2,
        "top" : getPageScroll()[1] + (getPageHeight() / 2)
    });
};

// getPageScroll() by quirksmode.com
function getPageScroll() {
    var xScroll, yScroll;
    if (self.pageYOffset) {
        yScroll = self.pageYOffset;
        xScroll = self.pageXOffset;
    } else if (document.documentElement && document.documentElement.scrollTop) {	 // Explorer 6 Strict
        yScroll = document.documentElement.scrollTop;
        xScroll = document.documentElement.scrollLeft;
    } else if (document.body) {// all other Explorers
        yScroll = document.body.scrollTop;
        xScroll = document.body.scrollLeft;
    }
    return new Array(xScroll,yScroll)
}

// Adapted from getPageSize() by quirksmode.com
function getPageHeight() {
    var windowHeight
    if (self.innerHeight) {	// all except Explorer
        windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
        windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
        windowHeight = document.body.clientHeight;
    }
    return windowHeight
}
