$(function() {

    // Resize item container.
    $(window).bind('resize', function() {
        var offset = $('#items').offset().top + 10;
        $('#items').height($(window).height() - offset);
        $('#cart').css('top', $('#navigation').position().top);
    }).trigger('resize');
    $('#items').css('overflow', 'auto');

    // Load cart
    var store = Gallery.Store.initialize();
    var cart = Gallery.Cart.initialize('#items', '#cart', store);
    var category = Gallery.Category.initialize('#category_selected', '#category_dropdown');

    // Handle mouse coordinates.
    $().mousemove(function(e) {
        Mouse.x = e.pageX;
        Mouse.y = e.pageY;
    });

});

Mouse = { x: 0, y: 0 };

var Gallery = {};

Gallery.Store = {
    data: {},
    initialize: function() {
        this.event_id = $('meta[name=event_id]').attr('content');
        this.restore();
        return this;
    },
    add: function(id, name, price, amount) {
        if (this.has(id)) {
            this.get(id).count++;
        } else {
            this.set(id, (name || ''), (price || ''), (amount || 1));
        }
        this.save();
        return this;
    },
    remove: function(id) {
        if (this.count(id) > 1) {
            this.get(id).count--;
            this.save();
        } else {
            this.del(id);
        }
        return this;
    },
    del: function(id) {
        delete this.data['item_' + id];
        this.save();
        return this;
    },
    has: function(id) {
        return (this.data['item_' + id.toString()]) ? true : false;
    },
    get: function(id) {
        return this.data['item_' + id.toString()];
    },
    count: function(id) {
        return this.has(id) ? this.get(id).count : 0;
    },
    set: function(id, name, price, amount) {
        this.data['item_' + id.toString()] = {
            id: id,
            name: name,
            price: price,
            count: amount
        };
        return this;
    },
    save: function() {
        $.cookie('sponsorshipGalleryCheckoutItems_' + this.event_id, $.toJSON(this.data), { path: '/' });
        return this;
    },
    restore: function() {
        var data = $.cookie('sponsorshipGalleryCheckoutItems_' + this.event_id);
        this.data = (data == null) ? {} : $.evalJSON(data);
        return this;
    },
    empty: function() {
        $.cookie('sponsorshipGalleryCheckoutItems_' + this.event_id, null, { path: '/' });
        this.data = {};
        return this;
    },
    length: function(dups) {
        var count = 0;
        var id;
        for (id in this.data) {
            count += (dups) ? this.data[id].count : 1;
        }
        return count;
    },
    toString: function() {
        var id, key, count;
        var result = "DataStore Dump:\n";
        for (id in this.data) {
            result += id + " (";
            var count = 0;
            for (key in this.data[id]) {
                if (count > 0) result += ", ";
                result += key + ":" + this.data[id][key];
                count++;
            }
            result += ")\n";
        }
        return result;
    },
    toArray: function() {
        var result = [];
        for (id in this.data) {
            result.push(this.data[id]);
        }
        return result;
    }
};

Gallery.Cart = {
    initialize: function(collection, container, store) {
        this.collection = $(collection);
        this.container = $(container);
        this.store = store;
        this.interval = null;
        this.collection.children('li').each($.bind(this, function(i, li) {
            var id = this.resolveId(li);
            var el = this.resolveElement(li);
            el.find('.information').cluetip({
                attribute: 'rel',
                local: true,
                hideLocal: true,
                showTitle: false,
                activation: 'click',
                dropShadow: true,
                width: 437,
                dropShadowSteps: 3,
                arrows: true,
                sticky: true,
                closeText: '<div class="tooltip_close"></div>'
            });
            if (el.hasClass('disabled') || el.hasClass('soldout')) {
                return;
            }
            el.css('background-color', '#ffffff');
            this[this.store.has(id) ? 'highlight' : 'unhighlight'](el);
            el.find('.price, .basket').click($.bind(this, function(e, li) { this.add(li); }, $(li)));
        }));
        this.container.find('.checkout').click($.bind(this, function(e) {
            if (this.store.length() > 0) {
                return true;
            } else {
                alert('You cannot checkout 0 items.');
                e.preventDefault();
                return false;
            }
        }));
        this.container.bind('mouseleave', $.bind(this, function() {
            this.startCloseTimer();
        }));
        this.container.bind('mouseenter', $.bind(this, function() {
            this.open();
        }));
        this.redraw();
        this.container.show();
        return this;
    },
    resolveElement: function(obj) {
        switch (typeof (obj)) {
            case 'string':
                return $('#item_' + obj);
            case 'number':
                return $('#item_' + obj.toString());
            case 'object':
                return $(obj);
            default:
                return null;
        }
    },
    resolveId: function(obj) {
        if (typeof (obj) == 'string') {
            return (obj.indexOf('_') == -1) ? obj : obj.substring(obj.indexOf('_') + 1);
        } else if (typeof (obj) == 'number') {
            return obj.toString();
        } else if (typeof (obj) == 'object') {
            return $(obj).attr('id').substring($(obj).attr('id').indexOf('_') + 1);
        }
        return null;
    },
    add: function(el) {
        var id = this.resolveId(el);
        el = this.resolveElement(el);
        if (this.store.count(id) == 0) {
            this.highlight(el);
        }
        var name = el.find('.title').text();
        var price = this.formatNumber(el.find('.price').text());
        this.store.add(id, name, price);
        this.redraw();
        this.open(2500);
    },
    remove: function(el) {
        var id = this.resolveId(el);
        el = this.resolveElement(el);
        this.store.remove(id);
        if (this.store.count(id) == 0) {
            this.unhighlight(el);
        }
        this.redraw();
    },
    highlight: function(el) {
        el = this.resolveElement(el);
        el.animate({ backgroundColor: '#fffb99' }).addClass('selected').find('.basket').removeClass('add').addClass('selected');
    },
    unhighlight: function(el) {
        el = this.resolveElement(el);
        el.animate({ backgroundColor: '#fff' }).removeClass('selected').find('.basket').removeClass('selected').addClass('add');
    },
    redraw: function() {
        this.container.find('.count').text(this.store.length() + ' item' + (this.store.length() != 1 ? 's' : ''));
        this.container.find('tbody').empty();
        var items = this.store.toArray();
        var total = 0;
        if (items.length > 0) {
            for (var i = 0; i < items.length; i++) {
                var price = this.formatNumber(items[i].price) * items[i].count;
                total += price;
                var li = $(
					'<tr>' +
						'<td class="name"><b>' + (i + 1) + '.</b> ' + items[i].name + '</td>' +
						'<td class="quantity">' + items[i].count + '</td>' +
						'<td class="price">' + this.formatNumber(price, true) + '</td>' +
						'<td class="remove"></td>' +
					'</tr>'
				);
                li.find('.remove').append(
					$('<a href="#">Remove</a>').attr('href', '#').click($.bind(this, function(e, id) {
					    e.preventDefault();
					    this.remove(id);
					    return false;
					}, items[i].id))
				);
                this.container.find('tbody').append(li);
            }
        } else {
            this.container.find('tbody').append('<tr><td class="empty" colspan="4">Your cart is empty.</td></tr>');
        }
        this.container.find('.total').text(this.formatNumber(total, true));
    },
    open: function(time) {
        this.container.find('.bin').slideDown('fast');
        this.startCloseTimer(time);
    },
    close: function() {
        this.container.find('.bin').slideUp('fast');
    },
    startCloseTimer: function(time) {
        time = time || 1000;
        this.clearCloseTimer();
        this.interval = setTimeout($.bind(this, function() {
            var l = this.container.offset().left;
            var t = this.container.offset().top;
            var r = l + this.container.width();
            var b = t + this.container.height();
            var x = Mouse.x;
            var y = Mouse.y;
            var o = (Mouse.x < l || Mouse.x > r || Mouse.y < t || Mouse.y > b) ? true : false;
            if (o) {
                this.close();
            }
        }), time);
    },
    clearCloseTimer: function() {
        clearInterval(this.interval);
    },
    formatNumber: function(number, toString) {
        var sign, cents;
        number = number.toString().replace(/\$|\,/g, '');
        if (isNaN(number)) {
            number = '0';
        }
        sign = (number == (number = Math.abs(number)));
        number = Math.floor(number * 100 + 0.50000000001);
        cents = number % 100;
        number = Math.floor(number / 100).toString();
        if (cents < 10) {
            cents = "0" + cents;
        }
        for (var i = 0; i < Math.floor((number.length - (1 + i)) / 3); i++) {
            number = number.substring(0, number.length - (4 * i + 3)) + (toString == true ? ',' : '') +
					 number.substring(number.length - (4 * i + 3));
        }
        number = (((sign) ? '' : '-') + (toString == true ? '$' : '') + number + '.' + cents);
        return (toString == true) ? number : parseFloat(number);
    }
};

Gallery.Category = {
    selector: null,
    dropdown: null,
    visible: false,
    initialize: function(selector, dropdown) {
        this.selector = $(selector);
        this.dropdown = $(dropdown);
        this.equalize();
        this.selector.click($.bind(this, this.toggle));
        $(document).click($.bind(this, this.checkOuterClick));
        return this;
    },
    equalize: function() {
        this.dropdown.css({ display: 'block', visibility: 'hidden' });
        var s_width = parseInt(this.selector.outerWidth());
        var d_width = parseInt(this.dropdown.outerWidth());
        if (s_width > d_width) {
            this.dropdown.width(s_width);
            this.dropdown.children('li').width(s_width);
            var offset = parseInt(this.dropdown.find('a').css('paddingLeft')) + parseInt(this.dropdown.find('a').css('paddingRight'));
            this.dropdown.find('a').width(s_width - offset);
        } else {
            this.dropdown.find('a').width(d_width);
        }
        this.dropdown.css({ display: 'none', visibility: 'visible' });
    },
    toggle: function() {
        this[(this.visible) ? 'close' : 'open']();
    },
    open: function() {
        this.visible = true;
        this.dropdown.slideDown('fast');
    },
    close: function() {
        this.visible = false;
        this.dropdown.slideUp('fast');
    },
    checkOuterClick: function(e) {
        var offset = this.selector.offset();
        var width = this.dropdown.width();
        var height = parseInt(this.selector.height()) + parseInt(this.dropdown.height());
        if (e.pageX > offset.left && e.pageX < offset.left + width) return;
        if (e.pageY < offset.top && e.pageY > offset.top + height) return;
        this.close();
    }
};
