window.console = window.console ? window.console : {log: function(m) { alert(m); }};

(function($) {
    // ----------------------------------------
    // View Classes
    // ----------------------------------------

    views = {};
    
    // Wrapped gifts
    function GiftWrapperPiece(view, $el) {
        this.view = view;
        this.$el = $el;
        this.update_position_timeout = null;

        this.offset = {
            'x': 0,
            'y': 0
        };
        
        var self = this;
        
        $el.bind('mousedown', function(e) {
            self.grab();
            $(this).unbind('mousedown');
        });
        
        $el.bind('mouseup', function(e) {
            self.drop();
            $(this).unbind('mouseup');
        });
    }

    GiftWrapperPiece.prototype.grab = function() {
        var self = this;

        this.offset = {
            'x': self.view.mouse_x - this.$el.position().left,
            'y': self.view.mouse_y - this.$el.position().top
        };

        this.update_position_timeout = setInterval(function() {
            self.$el.css({
                'left': self.view.mouse_x - self.offset.x + 'px',
                'top': self.view.mouse_y - self.offset.y + 'px'
            });
        }, 1000 / 60);
    }
    
    GiftWrapperPiece.prototype.drop = function() {
        if(this.update_position_timeout) {
            clearInterval(this.update_position_timeout);
        }

        this.$el.animate({
            'top': $(document).height()
        });
    }
    
    views.WrappedGiftView = function($el) {
        var self = this;
        this.$el = $el;
        
        this.$wrapper_el = $($('#gift-wrapper-template').html());
        this.$el.after(this.$wrapper_el);
        
        var el_pos = this.$el.position();
        
        this.$wrapper_el.css({
            'left': el_pos.left,
            'top': el_pos.top
        });

        this.$wrapper_el.find('.gift-wrapper').each(function() {
            new GiftWrapperPiece(self, $(this));
        });

        $('body').bind('mousemove', function(e) {
            self.mouse_x = e.clientX;
            self.mouse_y = e.clientY;
        });
    }

    views.WrappedGiftView.prototype.remove = function(piece) {
        this.$el.remove(piece.$el);
        
        if(this.$el.find('.gift-wrapper').length == 0) {
            alert('all unwrapped');
        }
    }
    // ---

    // Homepage gift image carousel
    function GiftCarouselItem($el) {
        this.$el = $el;
        this.offset = $el.css('left');
    }
    
    views.GiftCarouselView = function($el) {
        this.$el = $el;
        this.$list_el = $el.find('ul');
        this.current_item_index = 0;
        this.carousel_items = [];
        this.advance_speed = 350;
        this.advance_delay = 1500;

        var self = this;
        
        var width_accum = 0;
        this.$list_el.find('li').each(function() {
            var $carousel_item = $(this);
            $carousel_item.css('left', width_accum + 'px');
            width_accum += $carousel_item.width();
            self.carousel_items.push(new GiftCarouselItem($carousel_item));
            
        });

        // Set up dummy clone fo first element for illusion
        // of wrap-around scrolling
        this.$dummy_last_el = $el.find('li').eq(0).clone();
        this.$dummy_last_el.css('left', width_accum + 'px');
        this.$list_el.append(this.$dummy_last_el);
        
        setTimeout(function() {
            self.advance();
        }, self.advance_delay);
    }

    views.GiftCarouselView.prototype.advance = function() {
        this.current_item_index += 1;


        var target_offset;
        if(this.current_item_index >= this.carousel_items.length) {
            target_offset = '-' + this.$dummy_last_el.css('left');
        } else {
            target_offset = '-' + this.carousel_items[this.current_item_index].offset;
        }
        
        var self = this;

        this.$list_el.animate({
            "left": target_offset
        }, self.advance_speed, 'swing', function() {
            if(self.current_item_index == self.carousel_items.length) {
                self.current_item_index = 0;
                self.$list_el.css('left', '0px');
            }
            
            setTimeout(function() {
                self.advance();
            }, self.advance_delay);        
        });
        
    }
    // ---

    // Collapsible text with 'read more' link
    views.CollapsibleTextView = function($el) {
        var self = this;
        
        this.$el = $el;
        var children = $.makeArray($el.children('p'));
        this.elements_to_hide = children.slice(1, children.length);

        if(this.elements_to_hide.length) {
            this.$more_less_toggle = $('<a class="collapsible-text-link" href="javascript:void(0);"></a>');
            this.$more_less_toggle.click(function() {
				self.toggle();
			});
            this.collapse(true);
        }
    }
    
    views.CollapsibleTextView.prototype.toggle = function() {
        if(this.is_collapsed) {
            this.expand();
        } else {
            this.collapse();
        }
    }
    
    views.CollapsibleTextView.prototype.collapse = function(skip_animation) {
        this.$el.children('p').eq(0).append(this.$more_less_toggle);
        
        this.$more_less_toggle.text("Read more");
        this.is_collapsed = true;

        for(var child in this.elements_to_hide) {
            if(skip_animation) {
                $(this.elements_to_hide[child]).hide();
            } else {
                $(this.elements_to_hide[child]).slideUp();                
            }
        }
    }
    
    views.CollapsibleTextView.prototype.expand = function() {
        this.$el.append(this.$more_less_toggle);
        
        this.$more_less_toggle.text("Read less");
        this.is_collapsed = false;
        for(var child in this.elements_to_hide) {
            $(this.elements_to_hide[child]).slideDown();
        }
    }
    // ---

    // Google maps div replacer
    views.GoogleMapsLocationView = function($el) {
        $el.empty();
        var raw_value = $el.data('location');
        
        var lat = parseFloat(raw_value.split(',')[0]);
        var lng = parseFloat(raw_value.split(',')[1]);

        var lat_lng = new google.maps.LatLng(lat, lng);
        var map_options = {
            zoom: 15,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            disableDefaultUI: true,
            zoomControl: true,
            center: lat_lng
        };

        var google_map = new google.maps.Map($el[0], map_options);

        var marker = new google.maps.Marker({
            position: lat_lng,
            map: google_map,
            draggable: false,
            animation: google.maps.Animation.DROP,
            title: "Here!"
        });
    }
    // ---

    // Image container view; help simulate a 1px inner border by
    // shuffling sizes around a bit. cf. style.css
    views.ImageContainerView = function($el) {
        var $img = $el.find('img').eq(0);
        $el.width($img.width() - 2);
        $el.height($img.height() - 2);        
    }
    // ---
    
    // Static "snowman rating" widget
    views.StaticSnowmanRatingView = function($el) {
        this.$el = $el;
        this.rating = parseFloat($el.data('rating'));
        this.rewriteMarkup();
        this.setSnowmenFromValue(this.rating);
    }

    views.StaticSnowmanRatingView.prototype.rewriteMarkup = function() {
        this.$snowmen_container = $('<div></div>');
        this.$snowmen_container.addClass('snowmen-container');

        for(var i=0; i<5; i++) {
            this.$snowmen_container.append($('<span class="snowman"></span>'));
        }

        this.$el.empty();
        this.$el.append(this.$snowmen_container);
    }

    views.StaticSnowmanRatingView.prototype.setSnowmenFromValue = function(val) {
        var half_snowman_count = Math.ceil(val / 0.5);
        var full_snowmen = Math.floor(half_snowman_count / 2);
        var has_half = half_snowman_count % 2 == 1;

        // Re-set all snowmen to 'empty'
        this.$snowmen_container.find('.snowman').removeClass('half').removeClass('full');
        
        for(var i=0; i<full_snowmen; i++) {
            this.$snowmen_container.find('.snowman').eq(i).addClass('full');
        }

        if(has_half) {
            this.$snowmen_container.find('.snowman').eq(full_snowmen).addClass('half');
        }
    }
    // ---

    // Give this gift button
    views.GiveGiftButtonView = function($el) {
        $el.click(function() {
            $('#give-gift-options').slideToggle();
            return false;
        });
    }
    // ---
    
    // ----------------------------------------    
    // Init
    // ----------------------------------------    
    $(function() {
        // `view_map` is like a dictionary of selectors -> functions
        // Each element matching each keyed selector has the value
        // function instantiated with the element as the only argument.
        // This is just an ultralight architecture for instantiating js
        // views from invidvidual DOM elements when they're present on
        // the page.
        var view_map = {
            '.wrapped-gift': views.WrappedGiftView,
            '#home-header-gift-carousel': views.GiftCarouselView,
            '.gift-review': views.CollapsibleTextView,
            '.gift-location': views.GoogleMapsLocationView,
            '.image-container': views.ImageContainerView,            
            '.snowman-rating-static': views.StaticSnowmanRatingView
            //'.give-gift-button': views.GiveGiftButtonView
        };

        for(var selector in view_map) {
            $(selector).each(function() {
                new view_map[selector]($(this));
            });
        }
    });
})(jQuery);

