function convert_milliseconds_to_mss(ms) {
    minutes = Math.floor(ms/60000);
    seconds = Math.floor((ms-60000*minutes)/1000);
    return minutes + ":" + seconds.toPaddedString(2);
};

var Streamer = Class.create({
    initialize: function(flash_object, playpause_id, playpause_toggle_class, stop_id, volume_bar_id, time_bar_id, current_time, end_time, url_fetcher, options) {
        this.flashobject = $(flash_object);
        this.playpause = $(playpause_id);
        this.playpause_toggleclass = playpause_toggle_class;
        this.stop_button = $(stop_id);
        this.volume_bar = $(volume_bar_id);
        this.time_bar = $(time_bar_id);
        this.buffered_time_bar = this.time_bar.down('div');
        this.played_time_bar = this.buffered_time_bar.down('div');
        this.current_time_text = $(current_time);
        this.end_time_text = $(end_time);
        this.url_fetcher = url_fetcher;
        this.autoplay = options.autoplay;
        
        streamer = this;
        this.playing = false;
        this.pending_stop_refresh = false;
        
        this.playpause.observe('click', function(s) {
            if (streamer.playing) {
                streamer.pause();
            } else {
                streamer.play();
            }
            s.stop();
        });
        
        this.stop_button.observe('click', function(s) {
            streamer.stop();
            s.stop();
        });
        
        this.volume_bar.observe('click', function(s) {
            volume_limit = streamer.volume_bar.cumulativeOffset()[0] + streamer.volume_bar.getWidth();
            if (s.pointerX() < volume_limit)
            {
                fraction = ( s.pointerX() - streamer.volume_bar.cumulativeOffset()[0] ) / streamer.volume_bar.getWidth();
                streamer.set_volume(fraction);
            }
            s.stop();
        });
        
        this.time_bar.observe('click', function(s) {
            buffer_limit = streamer.buffered_time_bar.cumulativeOffset()[0] + streamer.buffered_time_bar.getWidth();
            if (s.pointerX() < buffer_limit)
            {
                percentage = ( s.pointerX() - streamer.buffered_time_bar.positionedOffset()[0] ) / streamer.time_bar.getWidth();
                streamer.goto_time(Math.floor(streamer.duration*percentage));
            }
            s.stop();
        });
    },
    onInit: function() {    // flash object's initialize
        this.set_volume(.5);
        if(this.autoplay)
        {
            this.play();
        }
    },
    onUpdate: function() {
        
        // Set play state
        this.set_play_state((this.isPlaying == 'true'));
        
        // Set buffer state
        this.buffered_time_bar.setStyle({width: 100*this.get_buffer_fraction()+"%"});
        
        // Set play position
        this.update_time_display(this.position);
        
        if (this.duration == 0) {
            if (this.zero_count == null) {
                this.zero_count = 1;
            } else {
                this.zero_count++;
            }
        }
        
        if (this.zero_count == 5) {
            this.stop();
            this.zero_count = 0;
            this.play();
        }

        if(this.pending_stop_refresh)
        {
            this.flashobject.SetVariable("enabled", "false");
        }
    },
    set_play_state: function(state) {
        this.playing = state;
        if(this.playing && this.playpause.hasClassName('paused'))
        {
            this.playpause.removeClassName('paused');
        }
        else if(!this.playing && !this.playpause.hasClassName('paused'))
        {
            this.playpause.addClassName('paused');
        }
    },
    play: function() {
        streamer = this;
        var begin_playing = function() {
            streamer.flashobject.SetVariable("method:play", "");
            streamer.pending_stop_refresh = false;
            streamer.set_play_state(true);
            streamer.flashobject.SetVariable("enabled", "true");
        };

        if (this.url == undefined || this.duration == 0) {
            this.load_song(begin_playing);
        } else {
            begin_playing();
        }
    },
    pause: function() {
        this.flashobject.SetVariable("method:pause", "");
        this.set_play_state(false);
        this.pending_stop_refresh = true;
    },
    stop: function() {
        this.flashobject.SetVariable("method:stop", "");
        this.set_play_state(false);
        this.update_time_display(0);
        this.pending_stop_refresh = true;
    },
    load_song: function(callback) {
        flashobject = this.flashobject;
        var load_and_callback = function(path) {
            flashobject.SetVariable("method:setUrl", path);
            callback();
        };
        this.url_fetcher(load_and_callback);
    },
    set_volume: function(volume_fraction) {
        this.volume_bar.down('div').setStyle({width: 100*volume_fraction + "%"});
        this.flashobject.SetVariable("method:setVolume", Math.round(200*volume_fraction));
    },
    get_buffer_fraction: function() {
        if (this.bytesLoaded == this.bytesTotal) {
            return 1;
        } else {
            return this.bytesLoaded / this.bytesTotal;
        }
    },
    goto_time: function(time) { // in milliseconds
        this.flashobject.SetVariable("method:setPosition", time);
        this.update_time_display(time);
    },
    update_time_display: function(time) {
        this.current_time_text.update(convert_milliseconds_to_mss(time));
        if (this.bytesPercent == 100)
        {
            this.end_time_text.update(convert_milliseconds_to_mss(this.duration));
        }
        else
        {
            this.end_time_text.update('--:--');
        }
        new_width_percentage = 0;
        if (this.position != null && this.duration != null) {
            new_width_percentage = 100*this.get_buffer_fraction()*this.position/this.duration+"%";
        }
        
        this.played_time_bar.setStyle({width:new_width_percentage});
    }
});
