AP.Poll = new Class(
{
    Implements: [Options, Events],

    options: {
        fxOptions: {
            link: 'cancel'
        }
    },

    initialize: function(element, options)
    {
        this.element = $(element);
        this.setOptions(options);
        this.id = this.element.get('id').replace(/^poll-/, '');
        this.append();
        this.element.store('AP-Poll', this);
    },

    append: function()
    {
        if (this.wrapper) return this;
        this.wrapper = this.element.getElement('> .wrapper');
        this.height = this.wrapper.setStyles({
            height: '',
            overflow: 'visible'
        }).getSize().y;
        this.wrapper.setStyles({
            height: this.height,
            overflow: 'hidden'
        });
        return this;
    },

    vote: function(id)
    {
        if (this.voted) return this;
        if (this.voting) return this;
        this.voting = true;
        this.element.addClass('loading');
        new Request.JSON({
            url: this.options.voteUrl.substitute({id: id}),
            method: 'get',
            onSuccess: function(response) {
                this.voted = true;
                this.voting = false;
                this.element.removeClass('loading');
                this.results();
                this.fireEvent('vote');
            }.bind(this)
        }).send({data:{nocache:(new Date).getTime()}});
        return this;
    },

    results: function()
    {
        if (this.loaded) return this;
        if (this.loading) return this;
        this.loading = true;
        this.element.addClass('loading');
        new Request.JSON({
            url: this.options.resultsUrl.substitute({id: this.id}),
            method: 'get',
            onSuccess: function(response) {
                this.data = response.records;
                this.loaded = true;
                this.loading = false;
                this.element.removeClass('loading');
                this.render();
                this.fireEvent('results');
            }.bind(this)
        }).send({data:{nocache:(new Date).getTime()}});
        return this;
    },

    render: function()
    {
        if (this.rendered) return this;
        if (!this.loaded) return this.load();
        this.content = this.element.getElement('.content');
        var record, html = '';
        for (var i = 0, l = this.data.length; i < l; i++) {
            record  = this.data[i];
            html   += this.options.resultTemplate.render({
                'class': 'record poll-answer' + (i == 0 ? ' first' : '') + (i == l - 1 ? ' last' : ''),
                id: 'answer-' + record.id,
                title: record.title,
                percent: record.percent,
                percent_round: record.percentRound,
                votes: record.votes,
                votes_human: record.votesAsString
            });
        }
        this.content.set('html', html);
        var newHeight = this.wrapper.setStyles({
            height: '',
            overflow: 'visible'
        }).getSize().y;
        this.wrapper.setStyles({
            height: this.height,
            overflow: 'hidden'
        });
        new Fx.Tween(this.wrapper, Object.merge({}, this.options.fxOptions, {
            property: 'height'
        })).start(newHeight);
        this.rendered = true;
        this.fireEvent('render');
        return this;
    }
});
