var Phototag = Class.create();

Phototag.prototype = {

    initialize: function(options) {

        this.url = options.getUrl;
        this.product_url = options.productUrl;
        this.skin_dir = options.skinDir;

        this.layers = {teaser: $(options.teaser), panel: null, tooltip: null, play: null};
        this.timeout = {tooltip: options.tooltipTimeout, slider: options.sliderTimeout};
        this.timer = {tooltip: null, slider: null};

        this.count = 0;
        this.data = null;
        this.products = [];
        this.mark = null;
        this.current = null;

        this.vars = {
            play_pressed: true,
            run_slideshow: true,
            show_tooltip: false
        }

        this.layers.panel = new Element('div', {'id': 'phototag-control'});
        this.layers.tooltip = new Element('div', {'id': 'phototag-tooltip'});
        this.layers.play = new Element('a', {'id': 'phototag-control-play', 'href': '#'});

        Event.observe(this.layers.play, 'click', this.playClicked.bindAsEventListener(this));

        this.layers.panel.hide();
        Element.insert(this.layers.teaser, this.layers.tooltip.hide());
        Element.insert(this.layers.panel, this.layers.play);
        Element.insert(this.layers.teaser, this.layers.panel);

        this.getData();

    },

    canSlide: function() {
        return this.vars.play_pressed && this.vars.run_slideshow && (this.count > 1);
    },


    redirect: function(sender, url) {
        window.location.href = url;
    },

    showTooltip: function(sender, mark_id, product_id, x, y) {
        this.vars.show_tooltip = true;
        this.mark = mark_id;
        if (x + 260 > this.layers.teaser.getWidth()) {
            this.layers.tooltip.setStyle({width: '260px', height: '240px', left: x - 272 + 'px', top: y + 'px'})
            this.layers.tooltip.addClassName('reverted');
        } else {
            this.layers.tooltip.setStyle({width: '260px', height: '240px', left: x + 'px', top: y + 'px'});
            this.layers.tooltip.removeClassName('reverted');
        }
        if (this.products[product_id] == null) {
            this.layers.tooltip.update('<div class="tooltip-please-wait"><img src="' + this.skin_dir + 'phototag-tooltip-please-wait.gif" /></div>').show();
            new Ajax.Request(this.product_url.gsub('product_id', product_id), {
                method : 'get',
                onSuccess: function(transport) {
                    this.products[product_id] = transport.responseText;
                    if (this.mark  == mark_id)
                        this.layers.tooltip.update(transport.responseText);
                }.bind(this),
                onFailure: function() {this.layers.tooltip.hide()}.bind(this)
            });
        } else {
            this.layers.tooltip.update(this.products[product_id]).show();
        }
        this.stopSlideshow();
        Event.observe(this.layers.tooltip, 'mouseover', this.clearTooltipTimer.bindAsEventListener(this));
        return this;
    },

    setSlideshowTimer: function() {
        clearTimeout(this.timer.slider);
        this.timer.slider = setTimeout(function() {this.next()}.bind(this), this.timeout.slider);
    },

    setTooltipTimer: function() {
        this.vars.show_tooltip = false;
        this.timer.tooltip = setTimeout(function() {this.hideTooltip()}.bind(this), this.timeout.tooltip);
        Event.stopObserving(this.layers.tooltip, 'mouseout');
        Event.observe(this.layers.tooltip, 'mouseover', this.clearTooltipTimer.bindAsEventListener(this));
    },

    clearTooltipTimer: function() {
        this.vars.show_tooltip = true;
        clearTimeout(this.timer.tooltip);
        Event.stopObserving(this.layers.tooltip, 'mouseover');
        Event.observe(this.layers.tooltip, 'mouseout', this.setTooltipTimer.bindAsEventListener(this));
    },

    hideTooltip: function() {
        if (!this.vars.show_tooltip) {
            this.layers.tooltip.hide();
            this.mark = null;
            this.startSlideshow();
        }
    },

    getData: function() {
        new Ajax.Request(this.url, {
            method: 'get',
            onSuccess: function(transport) {
                this.data = transport.responseText.evalJSON();
                this.count = this.data.length;
                this.current = 0;
                this.addControls();
                this.setSlideshowTimer();
                this.setSlideActive(0);
                this.reload();
            }.bind(this)
        });
        this.layers.play.update('Pause').removeClassName('phototag-play').addClassName('phototag-pause');
    },

    reload: function() {
        this.hideMarks();
        this.hideTooltip();
        var imageObj = new Image();
        imageObj.onload = function() {
            this.layers.teaser.setStyle({backgroundImage: 'url(' + this.data[this.current].path + ')'});
            this.layers.teaser.setStyle({backgroundPosition: 'top left'});
            this.showMarks();
            this.showControls();
        }.bind(this);
        imageObj.src = this.data[this.current].path;
        return this;
    },

    addControls: function() {
        if (this.count > 1) {
            this.data.each(function(photo, key) {
                var control = new Element('a', {'rel': key, 'href': '#', 'class': 'phototag-slide'}).update(key + 1);
                control.addClassName('phototag-slide');
                Event.observe(control, 'click', this.showSlide.bindAsEventListener(this));
                Element.insert(this.layers.panel, control);
            }.bind(this));
        }
    },

    showMarks: function() {
        if (this.data[this.current].marks) {
            this.data[this.current].marks.each(function(mark) {
                var image = $('mark-' + mark.id);
                if (image == null) {
                    image = new Element('img', {'id': 'mark-' + mark.id, 'src': this.skin_dir + 'phototag-mark.png', 'alt': mark.title}).addClassName('phototag-mark').setStyle({left: mark.x + 'px', top: mark.y + 'px', height: '31px', width: '31px'});
                    Element.insert(this.layers.teaser, image);
                }
                Event.observe(image, 'mouseout', this.setTooltipTimer.bindAsEventListener(this));
                Event.observe(image, 'mouseover', this.showTooltip.bindAsEventListener(this, mark.id, mark.product_id, parseInt(mark.x) + 24, parseInt(mark.y) - 6));
                Event.observe(image, 'click', this.redirect.bindAsEventListener(this, mark.product_url));
                image.show();
            }.bind(this));
        }
        return this;
    },

    hideMarks: function() {
        var marks = $$('#' + this.layers.teaser.identify() + ' .phototag-mark');
        marks.each(function(mark) {
            mark.hide();
        });
        return this;
    },

    showControls: function() {
        if (this.count > 1 && !this.layers.panel.visible()) {
            this.layers.panel.show();
        }
        return this;
    },

    hideControls: function() {
        this.layers.panel.hide();
        return this;
    },

    next: function() {
        if (this.canSlide()) {
            if (this.current < this.count - 1)
                this.setSlideActive(++this.current);
            else
                this.setSlideActive(0);
        }
        this.setSlideshowTimer();
        return this;
    },

    prev: function() {
        if (this.canSlide()) {
            if (this.current > 0)
                this.setSlideActive(--this.current);
            else
                this.setSlideActive(this.count - 1);
        }
        this.setSlideshowTimer();
        return this;
    },

    showSlide: function(event) {
        event.stop();
        this.setSlideActive(event.element().readAttribute('rel'));
        this.setSlideshowTimer();
        return this;
    },

    setSlideActive: function(number) {
        if (this.count > number) {
            $$('.phototag-slide').invoke('removeClassName', 'active');
            var current_button = $$('.phototag-slide[rel='+number+']').first();
            if (current_button != undefined) current_button.addClassName('active');
            this.current = number;
            this.reload();
        }
        return this;
    },

    playClicked: function(event) {
        event.stop();
        if (this.vars.play_pressed) {
            this.vars.play_pressed = false;
            this.layers.play.update('Play').removeClassName('phototag-pause').addClassName('phototag-play');
        } else {
            this.vars.play_pressed = true;
            this.layers.play.update('Pause').removeClassName('phototag-play').addClassName('phototag-pause');
        }
        return this;
    },

    startSlideshow: function() {
        this.vars.run_slideshow = true;
        return this;
    },

    stopSlideshow: function() {
        this.vars.run_slideshow = false;
        return this;
    }
}

