/**
 * JQuery UI Product variant plugin.  This may be called on any element; the element
 *
 *
 * @author Hemant Patel
 * @dependency ui.core.js
 * @dependency ui.combobox.js
 * @version 1.0
 */

;(function($){

    $.widget("ui.variants", {

        _init: function(){
          //  console.log(this)
            var self = this,
                options  = this.options,
                product = options.product,
				remote = options.remote,

                uiVariants = this.uiVariants =  this.element
            .addClass("ui-variants ui-widget ui-helper-clearfix");

            if (product.variants.length > 1){
				        this._createVariants(product);

            }

            if(product.variants.length == 1){
                self._setData("variant", {
                    id: product.variants[0].id,
                    in_stock: product.variants[0].in_stock,
                    on_hand: product.variants[0].on_hand
                });
            }

            if(options.withButtons){
                var formContainer = $(this.options.appendFormTo)
                var variantForm = (this.variantForm = $('<form/>'))
                .appendTo(formContainer)
                .addClass('ui-variant-form')
                .attr({
                    method: 'post',
                    action: options.url
                })

                if(options.authenticity_token)
                    variantForm.append('<input type="hidden" name="authenticity_token" value="'+ options.authenticity_token +'" />')

                var selectedVariantField = (this.selectedVariantField = $('<input type="hidden" name="variant_id" class="ui-selected-variant"/>'))
                .appendTo(variantForm);

                this.button = new $.ui.variants.button(this)
                this.button.$el
                .appendTo(variantForm)
                .addClass('ui-variant-button')
                .attr('id','variant-submit-button')

                if(product.units_on_hand > 0  &&  product.variants.length > 1){
                    $.ui.variants.button.makeCart()
                    $.ui.variants.button.disabled()
                }else if(product.units_on_hand > 0  &&  product.variants.length == 1){
                    $.ui.variants.button.makeCart();

                    self._setData("variant", {
                        id: product.variants[0].id,
                        in_stock: product.variants[0].in_stock,
                        on_hand: product.variants[0].on_hand
                    });

                    selectedVariantField.val(product.variants[0].id)
                    $.ui.variants.button.enabled();

                }else if(product.units_on_hand == 0 && product.is_vintage == 1){
                    $.ui.variants.button.makeStock()
                }else if(product.units_on_hand == 0 && product.variants.length > 1){
                    $.ui.variants.button.makeNotify()

					self._setData("variant", {
                        id: 0,
                        in_stock: product.variants[0].in_stock,
                        on_hand: product.variants[0].on_hand
                    });

                    selectedVariantField.val("0")
					$('#notify-variant').val("0")
                    $.ui.variants.button.enabled();

					notifyLink = $('<a href="#notify_me_popup" id="notify_link_text"/>')
	                .addClass('ui-notify-link')
	                .text("Notify Me On Restock")
					.click( function(e){
	                    self.notifyMe(e)
	                    return false;
	                })
	
					self.generateNewNotify(notifyLink)
					$('#outofstock_bubble').fadeIn('slow')
                }
				else if(product.units_on_hand == 0 && product.variants.length == 1){
					$.ui.variants.button.makeNotify();

                    self._setData("variant", {
                        id: product.variants[0].id,
                        in_stock: product.variants[0].in_stock,
                        on_hand: product.variants[0].on_hand
                    });

                    selectedVariantField.val(product.variants[0].id)
                    $.ui.variants.button.enabled();

					notifyLink = $('<a href="#notify_me_popup" id="notify_link_text"/>')
	                .addClass('ui-notify-link')
	                .text("Notify Me On Restock")
	                .click( function(e){
	                    self.notifyMe(e)
	                    return false;
	                })
					self.generateNewNotify(notifyLink)
					$('#outofstock_bubble').fadeIn('slow')

                }


                this.button.$el.click(function(event){

                    if ($.ui.variants.button.isCartButton()
                        && $.ui.variants.button.isEnabled()
                        &&  self.selectedVariantField.val())
						{
                        	if(remote==true)
							{
								$.ajax({
									async:true, 
									data:$.param(self.variantForm.serializeArray()) + '&amp;authenticity_token=' + encodeURIComponent(options.authenticity_token), 
									dataType:'script', 
									type:'post', 
									url:options.url
								}); 
								return false;
							}
							else{
                        		self.variantForm.submit();
							}
						}

                    if ($.ui.variants.button.isCartButton() && $.ui.variants.button.isDisabled()){
                        availabletypes = []
                        $.each($('.ui-variant-container'),function(i, container){
                            availabletypes.push($(container).attr('id'))
                        });
						
                        	if(availabletypes.length == 2){
	                            self.showError("Please select available "+ availabletypes.join(' and '), "other")
	                        }else if(availabletypes.length > 2) {
	                            lastVal = availabletypes.pop()
	                            self.showError("Please select available "+ availabletypes.join(', ') + " and " + lastVal, "other")
	                        }else{
	                            self.showError("Please select available "+ availabletypes[0], "other")
	                        }
						
                    }

                    if($.ui.variants.button.isNotifyButton()) {
				variant = self._getData('variant')
                        self._trigger('notifyMe', event, variant)
                    }

                    return false;
                });
            }


            var selectedVariant = this.selectedVariant = {}
            var selectedValue =  this.selectedValue = {}


        },

        destroy: function() {
            if(!this.element.data('variant')) return;
            this.uiVariants.hide()
		        this.element
            .removeData("variant")
			      .unbind(".variants")
			     	.hide()
		        this.uiVariants.remove();

            $.widget.prototype.destroy.apply(this, arguments);
        },

        _createVariants: function(product){

            var self = this,
                variantPane = (this.uiVariantPane = $("<div></div>").addClass('ui-variant-pane'));

            $.each(product.variants[0].custom_values, function(custom_index, custom_value){

                var fieldFormat = custom_value.custom_field.field_format
                var fieldName =  custom_value.custom_field.name
                var fieldIdentifier = custom_value.custom_field.identifier

                if(fieldFormat != 'sizes'){
                	var variantContainer = $('<div style="display:inline"></div>')
					.addClass('ui-variant-container ui-variant-'+fieldFormat)
	                .attr({id: fieldName})
				}
				else{
					var variantContainer = $('<div></div>')
					.addClass('ui-variant-container ui-variant-'+fieldFormat)
	                .attr({id: fieldName})
				}
                

                var variantValues = self._extractVariantsFor(fieldIdentifier,product.variants)

                if(fieldFormat != 'sizes'){
                    var selectField = $('<input type="text" id="'+fieldName+'" value="Select a '+ fieldName +'">')
                    .addClass('ui-variant-value-select')
                }else{
                    $('<h4> Select A ' + fieldName + '</h4>').appendTo(variantContainer)
                }
                var optionsMap = {}, optionsData=[]
                $.each(variantValues, function(value_index, variant){
                    if(fieldFormat == 'sizes'){

                        sizeButton = $('<input type="button"/>').css('outline', 0)
                        .addClass('ui-variant-value size-button ui-corner-all')
                        .attr({
                            name:'variant_'+fieldIdentifier,
                            id: 'variant-size-'+ value_index,
                            value: variant.value
                        })
                        .hover(
						                function() {
                                if($(this).hasClass('in-stock'))
							                      $(this).addClass('ui-state-hover-in-stock');
                                else{
                                    $(this).addClass('ui-state-hover-out-of-stock');
                                }
						                },
						                function() {
                                if($(this).hasClass('in-stock'))
                                    $(this).removeClass('ui-state-hover-in-stock');

                                else{
                                    $(this).removeClass('ui-state-hover-out-of-stock');

                                }
                   					}
					              )
					              .focus(function() {
						                $(this).addClass('ui-state-focus');
					              })
					              .blur(function() {
						                $(this).removeClass('ui-state-focus');
					              })
                        .mousedown(function(ev) {
					                  ev.stopPropagation();
				                })
                        .click(function(event) {
                            event.preventDefault();
					                  self.selectValue(event, $(this), self)
                        })
                        .appendTo(variantContainer)

                        if(variant.on_hand <= 0){
                            sizeButton.addClass('out-of-stock')
                        }else{
                            sizeButton.addClass('in-stock')

                        }


                    }else{

                         if(variant.on_hand <= 0){
                             optionsMap[variant.value] = {val: variant.value, className: 'ui-variant-value out-of-stock'}

                         }else{
							               optionsMap[variant.value] = {val: variant.value, className: 'ui-variant-value in-stock'}
                         }
                        optionsData.push(variant.value)

                    }

                });

                if (fieldFormat != 'sizes'){
                    selectField.appendTo(variantContainer)

                    var selectCombo =  selectField.combobox({
                        data: optionsData,
                        listHTML: function(val, index){
                            cls = optionsMap[val].className
							              return '<span class = "ui-combobox-item ' + cls + '">' + val + '</span>';
                        },
                        select: function(event, ui){
                            self.selectValue(event, $(this), self);
                        }
                    });



                }


                variantContainer.appendTo(self.uiVariantPane);

            });
            self.uiVariantPane.appendTo(this.uiVariants)
        },

        _extractVariantsFor: function(fieldIdentifier,variants){
            extracted_values = []
            check_value =[]
            $.each(variants, function(index, variant){
                $.each(variant.custom_values, function(value_index, variant_value){

                    if (variant_value.custom_field.identifier == fieldIdentifier){
                        if ($.inArray(variant_value.value, check_value) == -1){
                            extracted_values.push({
                                value: variant_value.value,
                                in_stock: variant.in_stock,
                                variant_id: variant.id,
                                on_hand: variant.on_hand,
                                field: variant_value.custom_field.identifier
                            });
                        }
                    }
                    check_value.push(variant_value.value);
                });

            });


            if (extracted_values.length > 0 &&  isNaN(extracted_values[0].value)){
                return extracted_values.sort( function(a,b){

                    var sizeOrder =  [
                        "XXS","XS", "XS / S",
                        "XS/S","S", "S/M", "S / M",
                        "Small/Medium", "M", "M / L", "M/L", "Medium/Large", "L", "L/XL", "L / XL",
                        "XL", "1X", "XXL", "2X", "3X" ]
                    return ($.inArray(a.value, sizeOrder) - $.inArray(b.value, sizeOrder))
                })
            }else{
                return extracted_values.sort(function(a,b){ return a.value - b.value});
            }


        },

        _isVariantSelected :function(){
            valuesToSelect = $('.ui-variant-container').size();
            selectedValues = $('div.ui-variant-value-selected').size();

            return (valuesToSelect == 0 || selectedValues == valuesToSelect)


        },

        getSelectedVariant :function(){
            var self = this
           // console.log("***********getSelectedVariant*********************")
           var variantSelected = {}
           var selectedValues = $('.ui-variant-value').filter('.in-stock-selected,.out-of-stock-selected')

            //$.each(selectedValues, function(i, selectedVal){
                name =  $(selectedValues[0]).parents('.ui-variant-container').attr('id')
                value =  $(selectedValues[0]).text()|| $(selectedValues[0]).attr('value')
                variantSelected[name] = value

            //});

            variantSelected = $.extend(variantSelected, this._checkStock(variantSelected))
            this.setSelectedVariant(variantSelected)
            return variantSelected
        },

        setSelectedVariant: function(selectedVariant){

            this.selectedVariant = selectedVariant
        },


        _prepareVariants : function(){
            var self = this
            var variants= {}
            function addVariant(variant){
                if(!(variant.id in variants))
                    variants[variant.id] = []
                fields = {}
                values = variant.custom_values_custom_fields
                $.each(values, function(i, val){
                    fields[val.name] = val.value
                });
                variants[variant.id].push($.extend({'values':fields}, {'in_stock': variant.in_stock, 'id': variant.id ,'on_hand': variant.on_hand}))

            }

            $.each(this.options.product.variants, function(i, variant){
                addVariant(variant)
            });

            return variants

        },

        _checkStock: function(selectedVariant){
            variants = this._prepareVariants();

            for(id in variants){
                inStockFound=[]
                $.each(variants[id][0].values, function(index, value){
                    inStockFound.push(value == selectedVariant[index] )

                });

                if($.inArray(false, inStockFound) == -1){
                    return {id: id, in_stock: variants[id][0].in_stock, on_hand: variants[id][0].on_hand, values: selectedVariant }
                }
            }



        },

        _filterValues: function(selectedValue, event){
            var self = this
            variants = this._prepareVariants();
            $el = $(event.target)

            this.selectedValue = $.extend(this.selectedValue, selectedValue)

            availableValues = []
            $.each(variants, function(index, variant){
                 found=[]
                $.each(variant[0].values, function(i, value){
                    found.push((value == self.selectedValue[i])  )

                });

                if (($.inArray(true, found) != -1) ){
                    availableValues.push(variant[0].values)
                }
            });

            $('.ui-variant-value').removeClass('available unavailable')

            if(availableValues.length > 0){
                $.each(availableValues, function(i, val){
                    $.each(val, function(key,value){
                        $('.ui-variant-value[value="'+value+'"]')
                        .removeClass('available unavailable')
                        .addClass('available')

                        $('.ui-variant-value:contains('+value+')')
                        .removeClass('available unavailable')
                        .addClass('available')

                    });
                });
            }

            if (self.options.product.variants[0].custom_values.length > 1){
                $('.ui-variant-value')
                .not('.available')
                .addClass('unavailable')
            }

            if($el.is('.ui-variant-value-select')){
                $el =  $('.ui-variant-value:contains('+$el.val()+')')
            }

            variantValues = $el.closest('div.ui-variant-container')
            .find('.ui-variant-value')
            .removeClass('in-stock-selected')
            .removeClass('out-of-stock-selected')
            .removeClass('ui-state-hover-in-stock')
            .removeClass('ui-state-hover-out-of-stock')


            if($el.hasClass('in-stock') && $el.hasClass('available')){
                $el.addClass('in-stock-selected')
            }else if(
                (($el.hasClass('unavailable') &&
                  $el.hasClass('out-of-stock')) ||
                 ($el.hasClass('in-stock') &&
                  $el.hasClass('unavailable')) ||
                 ($el.hasClass('out-of-stock') &&
                  ($el.hasClass('available'))))){

                $el.addClass('out-of-stock-selected')
            }

             self._refreshVariants($el)


        },

        isVariantSelected: function(){
            return  this._isVariantSelected()
        },

        selectValue: function(event, $el,context ){
            var self = context

            var selectedValue ={}

            var field = $el.parents('.ui-variant-container').attr('id')
            selectedValue[field] = $el.attr('value')


            self._filterValues(selectedValue, event)


            self.hideError()

			$('#winston_bag_notification').fadeOut('slow')


            if( self.isVariantSelected()){

                var selectedVariant = self.getSelectedVariant()

                if(selectedVariant.in_stock != null && selectedVariant.in_stock){

                    self.hideError()

                    if(self.options.withButtons){
                        if(!($.ui.variants.button.isCartButton()))
                            $.ui.variants.button.makeCart()
                        $.ui.variants.button.enabled()
                        self.selectedVariantField.val(selectedVariant.id)

                    }

                    self._setData("variant", selectedVariant)

                   // this.selectedValue = {}
                    self._trigger('inStockVariantSelected', event, selectedVariant)

                }else if(selectedVariant.in_stock != null && !selectedVariant.in_stock){

                    self._setData("variant", selectedVariant)
					self.selectedVariantField.val(selectedVariant.id)

                    if(self.options.displayError){
                        self.showNotify(event, $el,selectedVariant)
                    }

                    self._trigger('outOfStockVariantSelected', event, selectedVariant)

                    if(self.options.withButtons){

                        if($.ui.variants.button.isCartButton())
                            $.ui.variants.button.disabled()

                        if($.ui.variants.button.isNotifyButton()){
                            self.showNotify(event, $el,selectedVariant)
                            $('a.ui-notify-link').trigger('click')

                        }

                    }



                }else{
                    errorMessage=""

                    for(key in selectedVariant){
                        errorMessage += key+ ": " + selectedVariant[key] + ", "
                    }

                    errorMessage += " is not available"

                    if(self.options.withButtons){
                        $.ui.variants.button.disabled()
                    }

                    if(self.options.displayError)
                        self.showError(errorMessage, "other")
                }

            }

            this.selectedValue = {}
            return false

        },

        _refreshVariants: function($el){


             $el.closest('div.ui-variant-container')
            .removeClass('ui-variant-value-selected in-stock-selected out-of-stock-selected')

            if($el.hasClass('in-stock-selected')){

                $el.closest('div.ui-variant-container')
                .addClass('ui-variant-value-selected in-stock-selected')

            }else if ($el.hasClass('out-of-stock-selected')) {

                $el.closest('div.ui-variant-container')
                .addClass('ui-variant-value-selected out-of-stock-selected')

            }

        },

        showNotify: function(event, $el,variantSelected){
            var self = this


            var  product = self.options.product
            var message = ""
            var values = []
            var filter = ["id","in_stock","on_hand"]

            for(key in variantSelected){
                if($.inArray(key, filter) < 0)
                    values.push( key + ": " + variantSelected[key])
            }

            message = ""
            if(values.length == 2){
                message = values.join(' and ') + " is out of stock"
            }else if (values.length > 2){
                lastVal = values.pop()
                message = values.join(', ') + " and " + lastVal + " is out of stock"
            }else{
                 message = values[0] + " is out of stock"
            }

            errorMessage = $("<div><p>"+message+"</p></div>")


            if(product.is_vintage != 1){
                notifyLink = $('<a href="#notify_me_popup"/>')
                .addClass('ui-notify-link')
                .text("Notify Me On Restock")
                .click( function(e){
                    self.notifyMe(e)
                    return false;
                })
               .appendTo(errorMessage)
            }
			this.showError(notifyLink, 'notify');

            ((self.options.withButtons)
             && (product.is_vintage == 1)
             && ($.ui.variants.button.isCartButton())
             && ( $.ui.variants.button.makeStock())
             && ( $.ui.variants.button.enabled()));

            ((self.options.withButtons)
             && (product.is_vintage == 0)
             && ($.ui.variants.button.isCartButton())
             && ($.ui.variants.button.disabled()));


        },

        showError: function(message, type){

           var self = this

            if($('.ui-variant-wrapper').length > 0)
                return $('.ui-variant-wrapper')


			if(type!="notify"){
				uiVariantPane = $('.ui-variant-pane').css({"float":"left" })
	            containerHeight = uiVariantPane.outerHeight(true)

	            var props = {height:containerHeight ,'float': uiVariantPane.css('float') };
            	wrapper = $('<div></div>')
	            .addClass('ui-variant-wrapper ui-variant-error-overlay ui-corner-all')
	            .css(props)


	            $('div.ui-variant-container')
	            .wrapAll(wrapper)
	            .wrapAll('<div></div>').parent().css('float','none');


	            if ($('.ui-error-content').length > 0) {
	                errorContent =  $('.ui-error-content').html('')
	            }else{
	                errorContent = $('<div/>').addClass('ui-error-content').css(props)
	            }

	            errorMessage = $('<div></div>')
	            .addClass('ui-error-message')
	            .css({height: containerHeight})

	            errorMessage.html(message)
	            errorMessage.css(props)
	            .appendTo(errorContent)

	            errorContent.insertBefore($('div.ui-variant-container').parent())
			}
			else{
				if(product.is_vintage != 1){
					$.ui.variants.button.makeNotify()
					self.generateNewNotify(message)
				}
			}


        },

		generateNewNotify: function(notify){
			var ext = $.browser.msie&&parseFloat($.browser.version)<7 ? 'gif' : 'png';
			$('#outofstock_bubble').remove()
			message = "<div id='outofstock_bubble' style='display:none;background:url(/images/notify_on_restock_bubble."+ext+") no-repeat top left;'><h1>Oh no! We're so sorry this item is sold out.</h1><p>We get the unique styles you love from indie designers who create them in small quantities, so often they sell out fast. But don't be sad...just click '<span id='notify_link'></span>', and we'll email you the moment this item is back in stock!</p><a onclick=\"$('#outofstock_bubble').fadeOut('slow')\">Close This Window</a></div>"
			$('div.add_to_bag_form').before(message);
			$('#notify_link').html(notify);
			$('#outofstock_bubble').fadeIn('slow')
		},

        notifyMe: function(event){
           var self = this

            variant = self._getData('variant')
            this._trigger('notifyMe',event,  variant)
            return false;
        },

        hideError: function(){
            uiVariantPane = $('.ui-variant-pane').css({"float":"none" })
            wrappedContainers = $('.ui-variant-container').css("float","none")

            if($('.ui-variant-wrapper').length > 0)
                return $('.ui-variant-wrapper').replaceWith(wrappedContainers)
            return wrappedContainers

        },

        _setData: function(key, value) {

		        switch (key) {
			      case 'variant':
				        this.options.variant = value;
               	break;
            case 'product':
                this.options.product = value;
                break;
		        }

		        $.widget.prototype._setData.apply(this, arguments);

	      }






    });

    $.extend($.ui.variants,{
        defaults: {
            product: {},
            url:'/storefront/cart/add',
            authenticity_token:'',
            highlightdelay: 3000,
            selectedVariantId: '',
            withButtons: true,
            variant:'',
            appendFormTo: 'div.add_to_bag_form',
            displayError: true

        },

        button: function(uiVariants) {
		        this.$el =  $.ui.variants.button.create(uiVariants);

	      },

        getSelectedVariantId: function(uiVariants){
            return this.selectedVariantId
        }



    });

    $.extend($.ui.variants.button,{
        type: '',
        state: '',

        events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
		                  function(event) { return event + '.variants-button'; }
                     ).join(' '),

        create: function(uiVariants){

            var $el = $("<div></div>")
            .addClass('ui-variants-button-pane')

            this.button =  $('<button type="button"></button>')
            .addClass('ui-variant-button ui-corner-all')
            .attr({id: 'variant-button'})
            .hover(
						    function() {
                    $(this).addClass('ui-state-hover-button')
						    },
						    function() {
                    $(this).removeClass('ui-state-hover-button')
							  })
					  .focus(function() {
						    $(this).addClass('ui-state-focus');
					  })
					  .blur(function() {
						    $(this).removeClass('ui-state-focus');
					  })
            .appendTo($el)

            return $el
        },

        destroy: function($el){

        },

        type: function(){
            return this.type

        },

        state: function(){
            return this.state
        },

        enabled: function(){
            this.state = 'enabled'
            this.button.removeClass('disabled').addClass('enabled')
			$('#outofstock_bubble').fadeOut('slow')

        },

        disabled: function(){
            this.state = 'disabled'
            this.button.removeClass('enabled').addClass('disabled')
        },

        setText: function(text){
            this.button.text(text)
        },

        isCartButton: function(){
            return   this.button.hasClass('cart-button')
        },

        isNotifyButton: function(){
            return   this.button.hasClass('notify-button')
        },

        isStockButton: function(){
            return   this.button.hasClass('stock-button')
        },

        isEnabled: function(){
            return   this.button.hasClass('enabled')
        },

        isDisabled: function(){
            return   this.button.hasClass('disabled')
        },

        makeCart: function(){
            this.state = "disabled"
            this.type = "cart-button"
			this.button.removeAttr("href").unbind('click')
            return this.button.removeClass('ui-notify-link stock-button enabled disabled')
            .addClass('cart-button disabled')
            .text('Add To Bag')


        },

        makeNotify: function(){

            this.state = "enabled"
            this.type = "notify-button"

            return  this.button.removeClass('cart-button stock-button enabled disabled')
            .addClass('ui-notify-link enabled')
            .text('Notify Me On Restock')
			.attr("href", "#notify_me_popup")

        },

        makeStock: function(){
            this.state = "enabled"
            this.type = "stock-button"

            return this.button.removeClass('cart-button notify-button enabled disabled')
            .addClass('stock-button disabled')
            .text('Sold')

        }


    });



})(jQuery);
