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;
}

function calculate_total_cost(product, variant, quantity) {
  if(product.using_price_types) {
    var price = variant.price;
    var price_type;
    for(var j in product.price_types) {
        if ( product.price_types[j].min_quantity > quantity )
            break;
        price_type = product.price_types[j];
    }
    if (price_type) {
        for(var i in variant.prices) {
            if ( variant.prices[i].price_type_id == price_type.id ) {
                price = variant.prices[i].price;
                break;
            }
        }
    }
    return price*quantity;    
  } else {
    var price = variant.price;
    var price_kind;
    var price_kinds = product.price_kinds.sort(function(a,b){
      return a.value - b.value;
    });

    for(var j in price_kinds) {
        if ( price_kinds[j].value > quantity )
            break;
        if( variant.prices[product.price_kinds[j].price_index - 1] ){
          price_kind = product.price_kinds[j];
        }
    }
    if (price_kind) {
        price = variant.prices[price_kind.price_index - 1];
    }
    return price*quantity;
  }
}

function get_prices(product, variant) {
  if(product.using_price_types) {
    var price_by_type = {};
    for(var i in variant.prices) {
        var price = variant.prices[i];
        price_by_type[price.price_type_id] = price;
    }
    var previous = null;
    var table = []
    for(var j in product.price_types) {
        var price_type = product.price_types[j];
        var price = variant.price;
        var to = price_type.min_quantity - 1;
        var from = 1;
        if (previous) {
            price = price_by_type[previous.id].price;
            from = previous.min_quantity;
        }
        table.push({ from: from, to: to, price: price});
        previous = price_type;
    }
    if (previous) {
        table.push({ from: previous.min_quantity, to: null, price: price_by_type[previous.id].price});
        return table;
    } else {
        return false;
    }
  } else {
    var prices = variant.prices;
    var previous = null;
    var table = [];
    var price_kinds = product.price_kinds.sort(function(a,b){
      return a.value - b.value;
    });

    for(var j in price_kinds) {
        var price_kind = price_kinds[j];
        if(prices[price_kind.price_index - 1]){
          var price = variant.price;
          var to = price_kind.value - 1;
          var from = 1;
          if (previous) {
              price = prices[previous.price_index-1];
              from = previous.value;
          }
          table.push({ from: from, to: to, price: price});
          previous = price_kind;
        }
    }
    if (previous) {
        table.push({ from: previous.value, to: null, price: prices[previous.price_index - 1]});
        return table;
    } else {
        return false;
    }
  }
}

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);
};

InSales.OrderLine = function(options) {
      this.init = function(options) {
          var line = this;
          $.each(options, function(key,value) { line[key] = value; });
          if (options.title) this.title = options.title.replace(/\+/g, ' ');
          if (options.sku) this.sku = options.sku.replace(/\+/g, ' ');
          this.url = '/product/?product_id=' + options.product_id;
      }
      
      this.image = function(format) {
          return this.image_url.replace('thumb', format);
      }

      this.init(options);
      return this;
}

InSales.Cart = function(drawCallback, format) {
    var cart = this;
    this.get_text = function(text) {
        if (!text) return text;
        return text.replace(/\+/g, ' ');
    }

    this.setCart = function(order) {
        if (!order) {
            this.total_price = 0;
            this.order_lines = [];
            this.items_count = 0;
            return;
        }
        this.total_price = order.total_price;
        var items_count = 0;
        var order_lines = [];
        $(order.order_lines).each(function(index, order_line) {
            items_count += order_line.quantity;
            order_lines[index] = new InSales.OrderLine(order_line);
        });
        this.order_lines = order_lines;
        this.items_count = items_count;
    }

    this.reloadCart = function(callback) {
        if ($.cookie('cart') != 'json') {
            cart.setCart($.parseJSON($.cookie('cart')));
            callback();
        } else {
            $.ajax({
                url: "/cart_items.json",
                dateType: 'json',
                success: function(order){
                    cart.setCart(order);
                    callback();
                }
            });
        }
    }

    this.removeItemTrigger = function(){
        $('[id^="delete_"]').each(function(i) {
            if ( $(this).attr('processed') ) { return; }
            $(this).attr('processed',true);
            var link = $(this);
            var variant_id = link.attr("id").replace("delete_","");
  
            $(this).click(function(e){
                e.preventDefault();
                cart.removeItem(variant_id);
           });
      });
    }

    this.removeItem = function(variant_id) {
        var fields =  new Object;
        fields['_method'] = 'delete';
        var path   = '/cart_items/' + variant_id + '.json';
        show_preloader();
        $.ajax({
            url:      path,
            type:     'post',
            data:     fields,
            dataType: 'json',
            success:  function(response) {
                cart.reloadCart(function(){
                    hide_preloader();
                    cart.draw();
                });
            },
            error:  function(response) {
                hide_preloader();
                console.log("Произошла ошибка.");
            }
        });     
    }
      
    this.addCallback = function() {
        this.reloadCart(function(){
            cart.draw();
            set_preloaders_message('<div id="add_product_notification">Товар добавлен в корзину</div>');
            window.setTimeout( hide_preloader, 1000);
        });
    }

    this.draw = function() {
        this.drawCallback(this);
        this.removeItemTrigger();
    }

    this.init = function(options) {
        this.drawCallback = options.draw;
        this.selector = options.selector;
        this.format = format;
        this.reloadCart(function(){
            cart.draw();
            initAjaxAddToCartButton(cart.selector, function(response){ cart.addCallback(); });
        });
    }

    this.init(drawCallback);
}


InSales.Compare = function(options) {
    var compare = this;
    this.get_text = function(text) {
        if (!text) return text;
        return text.replace(/\+/g, ' ');
    }

    this.reload = function() {
        this.products = $.parseJSON($.cookie('compare'));
        if (!this.products) {
            this.products = [];
            return;
        }
        $(this.products).each(function(index, product) {
            product['title'] = compare.get_text(product['title']);
        });
    }

    this.removeItemTrigger = function(){
        $('.remove_compare').each(function(i) {
            if ( $(this).attr('processed') ) { return; }
            $(this).attr('processed',true);
            var product_id = $(this).attr('rel');

            $(this).click(function(e){
                e.preventDefault();
                compare.removeItem(product_id);
           });
      });
    }

    this.removeItem = function(product_id) {
        var fields =  new Object;
        fields['_method'] = 'delete';
        var path   = '/compares/' + product_id + '.json';
        show_preloader();
        $.ajax({
            url:      path,
            type:     'post',
            data:     fields,
            dataType: 'json',
            success:  function(response) {
                $('.compare_' + product_id).remove();
                compare.reload();
                hide_preloader();
                compare.draw();
            },
            error:  function(response) {
                hide_preloader();
            }
        });
    }

    this.addItemTrigger = function() {
        $(this.selector).click(function(){
            var product_id = $(this).attr('rel');
            var path   = '/compares.json';
            show_preloader();
            $.ajax({
                url:      path,
                type:     'post',
                data:     {'product[id]': product_id},
                dataType: 'json',
                success:  function(response) {
                    compare.reload();
                    compare.draw();
                    set_preloaders_message('<div id="add_product_notification">Товар добавлен к сравнению</div>');
                    window.setTimeout(hide_preloader, 1000);
                },
                error:  function(response) {
                    hide_preloader();
                }
            });
        });
    }

    this.draw = function() {
        this.drawCallback(this.products);
        this.removeItemTrigger();
    }

    this.init = function(options) {
        this.drawCallback = options.draw;
        this.selector = options.selector;
        this.reload();
        this.draw();
        this.addItemTrigger();
    }

    this.init(options);
}

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;
    };

    this.getCurrVariant = function() {
        var currValues = this.selectedValues(); // get current values
        return this.product.getVariant(currValues);
    };

    // callback when a selector is updated.
    this.updateSelectors = function(index) {
        var variant    = this.getCurrVariant();
        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.filterOptionValues = function(){
        // Создаём массив значений св-в каждой модификации
        var variants_option_values = [];
        for (var i = 0; i < this.product.variants.length; i++) {
            var variant = this.product.variants[i];
            //if (!variant.available) continue;
            var variant_option_values = []
            jQuery.each(variant.option_values, function(index,option_value) {
                variant_option_values.push(option_value.title);
            });
            variants_option_values.push(variant_option_values)
        }

        var id_prefix = 'variant-select-option-';
        var max_option_name_index = jQuery('.single-option-selector').size() - 1;
        // При выборе значения св-ва у следующего св-ва оставляем только те значения, которые могут быть у товара при выбранных предыдущих значениях
        jQuery('.single-option-selector').live('change',function(){
            var selected_option_value = jQuery(this).val();
            var id = jQuery(this).attr('id');
            var option_name_index = parseInt(id.replace(id_prefix,''));
            if (option_name_index == max_option_name_index) return;
            var next_option_name_index = option_name_index + 1;
            var option_values = [];
            jQuery.each(variants_option_values, function(index,variant_option_values){
                var current_option_value = variant_option_values[option_name_index];
                if (current_option_value == selected_option_value) {
                    var allowed_option_value = true
                    // проходимся по ранее выбранным значениям св-в
                    for (var i=option_name_index; i >= 0; i--){
                        var prev_current_option_value = jQuery("#"+id_prefix+i).val();
                        if (variant_option_values[i] != prev_current_option_value) allowed_option_value = false;
                    }
                    if (allowed_option_value){
                        var next_option_value = variant_option_values[next_option_name_index];
                        option_values = jQuery.grep(option_values, function (option_value) {return option_value != next_option_value;});
                        option_values.push(next_option_value);
                    }
                }
            });
            
            var next_option_values_select = jQuery("#"+id_prefix+next_option_name_index);
            var next_slected_option_value = next_option_values_select.val();

            var options = "";
            jQuery.each(option_values, function(){
                var selected = "";
                if (this == next_slected_option_value) selected = "selected='selected'"
                options += "<option value='"+this+"' "+ selected +">"+this+"</option>";
            });
            
            next_option_values_select.html(options);
            next_option_values_select.trigger('change');
        });

        $("#"+id_prefix+0).trigger('change');
    }

    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();

    if (options['filterOptionValues']) this.filterOptionValues(); // Поочерёдная фильтрация значения св-в.
    
    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();});
                    }, 6000);
                } 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
}

