YAHOO.namespace('zoeyplayer');

YAHOO.zoeyplayer.sm2_load_success = new YAHOO.util.CustomEvent('sm2_load_success');
YAHOO.zoeyplayer.sm2_load_failure = new YAHOO.util.CustomEvent('sm2_load_failure');


ua = navigator.userAgent;

YAHOO.zoeyplayer.isTouchDevice = (ua.match(/ipad|ipod|iphone/i));


YAHOO.zoeyplayer.PlayableItem = function(url) {
    this.createEvent('item_playback_started');
    this.createEvent('item_playback_stopped');
    this.createEvent('item_playback_paused');
    this.createEvent('item_playback_resumed');
    this.createEvent('item_playback_finished');
    this.createEvent('item_load_finished');
    this.createEvent('item_metadata_received');

    this.playback_url = url;
    this.download_url = null;
    this.album_url = null;
    this.track_url = null;
    this.artbook_url = null;
    this.artwork_url = '/media/img/unknown-album-art.png';
    this.artist_name = 'Unknown Artist';
    this.album_title = 'Unknown Album';
    this.track_title = 'Unknown Title';
    this.track_number = 0;
    this.sound_id = null;
    this.sound_object = null;
};
YAHOO.zoeyplayer.PlayableItem.cache = {};
YAHOO.zoeyplayer.PlayableItem.get = function(url) {
    var item = YAHOO.zoeyplayer.PlayableItem.cache[url];
    if (typeof(item) == 'undefined') {
        item = new YAHOO.zoeyplayer.PlayableItem(url);
    }
    YAHOO.zoeyplayer.PlayableItem.cache[url] = item;
    return item;
};
YAHOO.zoeyplayer.PlayableItem.prototype.onPlay = function(manager) {
    this.fireEvent('item_playback_started', {
        manager: manager,
        sound: this.sound_object,
        playable_item: this
    });
};
YAHOO.zoeyplayer.PlayableItem.prototype.onPause = function(manager) {
    this.fireEvent('item_playback_paused', {
        manager: manager,
        sound: this.sound_object,
        playable_item: this
    });
};
YAHOO.zoeyplayer.PlayableItem.prototype.onResume = function(manager) {
    this.fireEvent('item_playback_resumed', {
        manager: manager,
        sound: this.sound_object,
        playable_item: this
    });
};
YAHOO.zoeyplayer.PlayableItem.prototype.onStop = function(manager) {
    this.fireEvent('item_playback_stopped', {
        manager: manager,
        sound: this.sound_object,
        playable_item: this
    });
};
YAHOO.zoeyplayer.PlayableItem.prototype.onFinish = function(manager) {
    this.fireEvent('item_playback_finished', {
        manager: manager,
        sound: this.sound_object,
        playable_item: this
    });
};
YAHOO.zoeyplayer.PlayableItem.prototype.onLoad = function(manager) {
    this.fireEvent('item_load_finished', {
        manager: manager,
        sound: this.sound_object,
        playable_item: this
    });
};
YAHOO.zoeyplayer.PlayableItem.prototype.onMetaData = function(manager) {
    this.fireEvent('item_metadata_received', {
        manager: manager,
        sound: this.sound_object,
        playable_item: this
    });
};
YAHOO.zoeyplayer.PlayableItem.prototype.isPlaying = function() {
    if (this.sound_object != null && this.sound_object.playState == 1) {
        return true;
    } else {
        return false;
    }
};
YAHOO.zoeyplayer.PlayableItem.prototype.isPaused = function() {
    if (this.sound_object != null && this.sound_object.paused == true) {
        return true;
    } else {
        return false;
    }
}
YAHOO.zoeyplayer.PlayableItem.prototype.getSoundId = function() {
    return this.sound_id;
};
YAHOO.zoeyplayer.PlayableItem.prototype.setSoundId = function(sound_id) {
    this.sound_id = sound_id;
    return this.getSoundId();
};
YAHOO.zoeyplayer.PlayableItem.prototype.getArtistName = function() {
    return this.artist_name;
};
YAHOO.zoeyplayer.PlayableItem.prototype.setArtistName = function(artist_name) {
    if (artist_name=='' || artist_name==null || artist_name==undefined) {
        return this.getArtistName();
    }
    this.artist_name = artist_name;
    return this.getArtistName();
};
YAHOO.zoeyplayer.PlayableItem.prototype.getAlbumTitle = function() {
    return this.album_title;
};
YAHOO.zoeyplayer.PlayableItem.prototype.setAlbumTitle = function(album_title) {
    if (album_title=='' || album_title==null || album_title==undefined) {
        return this.getAlbumTitle();
    }
    this.album_title = album_title;
    return this.getAlbumTitle();
};
YAHOO.zoeyplayer.PlayableItem.prototype.getTrackTitle = function() {
    return this.track_title;
};
YAHOO.zoeyplayer.PlayableItem.prototype.setTrackTitle = function(track_title) {
    if (track_title=='' || track_title==null || track_title==undefined) {
        return this.getTrackTitle();
    }
    this.track_title = track_title;
    return this.getTrackTitle();
};
YAHOO.zoeyplayer.PlayableItem.prototype.getPlaybackUrl = function() {
    return this.playback_url;
};
YAHOO.zoeyplayer.PlayableItem.prototype.setPlaybackUrl = function(playback_url) {
    if (playback_url=='' || playback_url==null || playback_url==undefined) {
        return this.getPlaybackUrl();
    }
    this.playback_url = playback_url;
    return this.getPlaybackUrl();
};
YAHOO.zoeyplayer.PlayableItem.prototype.getArtworkUrl = function() {
    return this.artwork_url;
};
YAHOO.zoeyplayer.PlayableItem.prototype.setArtworkUrl = function(artwork_url) {
    if (artwork_url=='' || artwork_url==null || artwork_url==undefined) {
        return this.getArtworkUrl();
    }
    this.artwork_url = artwork_url;
    return this.getArtworkUrl();
};
YAHOO.zoeyplayer.PlayableItem.prototype.getArtbookUrl = function() {
    return this.artbook_url;
};
YAHOO.zoeyplayer.PlayableItem.prototype.setArtbookUrl = function(artbook_url) {
    if (artbook_url=='' || artbook_url==null || artbook_url==undefined) {
        return this.getArtbookUrl();
    }
    this.artbook_url = artbook_url;
    return this.getArtbookUrl();
};
YAHOO.zoeyplayer.PlayableItem.prototype.getTrackUrl = function() {
    return this.track_url;
};
YAHOO.zoeyplayer.PlayableItem.prototype.setTrackUrl = function(track_url) {
    if (track_url=='' || track_url==null || track_url==undefined) {
        return this.getTrackUrl();
    }
    this.track_url = track_url;
    return this.getTrackUrl();
};
YAHOO.zoeyplayer.PlayableItem.prototype.getAlbumUrl = function() {
    return this.album_url;
};
YAHOO.zoeyplayer.PlayableItem.prototype.setAlbumUrl = function(album_url) {
    if (album_url=='' || album_url==null || album_url==undefined) {
        return this.getAlbumUrl();
    }
    this.album_url = album_url;
    return this.getAlbumUrl();
};
YAHOO.zoeyplayer.PlayableItem.prototype.getArtistUrl = function() {
    return this.artist_url;
};
YAHOO.zoeyplayer.PlayableItem.prototype.setArtistUrl = function(artist_url) {
    if (artist_url=='' || artist_url==null || artist_url==undefined) {
        return this.getArtistUrl();
    }
    this.artist_url = artist_url;
    return this.getArtistUrl();
};
YAHOO.zoeyplayer.PlayableItem.prototype.getDuration = function() {
    var sound_object = this.sound_object;
    if (sound_object.instanceOptions.isMovieStar) {
        return sound_object.duration;
    } else {
        if (sound_object.durationEstimate) {
            return sound_object.durationEstimate;
        } else {
            return sound_object.duration;
        }
    }
};
YAHOO.lang.augmentProto(YAHOO.zoeyplayer.PlayableItem, YAHOO.util.EventProvider);


YAHOO.zoeyplayer.Playlist = function(title) {
    this.createEvent('playlist_item_inserted');
    this.createEvent('playlist_item_removed');
    this.item_list = [];
    this.title = 'Playlist';
    if (YAHOO.lang.isString(title)) {
        this.setTitle(title);
    }
};
YAHOO.zoeyplayer.Playlist.prototype.getTitle = function() {
    return this.title;
};
YAHOO.zoeyplayer.Playlist.prototype.setTitle = function(title) {
    this.title = title;
    return this.getTitle();
};
YAHOO.zoeyplayer.Playlist.prototype.insert = function(item, index) {
    if (item instanceof YAHOO.zoeyplayer.PlayableItem) {
        this.insertItem(item, index);
    } else if (item instanceof YAHOO.zoeyplayer.Playlist) {
        for (item_index in item.item_list) {
            this.insert(item.item_list[item_index], index + item_index);
        }
    }
};
YAHOO.zoeyplayer.Playlist.prototype.append = function(item) {
    return this.insert(item, this.item_list.length);
};
YAHOO.zoeyplayer.Playlist.prototype.insertItem = function(item, index) {
    if (index == this.item_list.length) {
        this.item_list[index] = item;
    } else {
        this.item_list.split(index, 0, item);
    }
    this.onInsertItem(item,index);
};
YAHOO.zoeyplayer.Playlist.prototype.hasItems = function() {
    if (this.item_list.length > 0) {
        return true;
    } else {
        return false;
    }
};
YAHOO.zoeyplayer.Playlist.prototype.getIndex = function(item) {
    var index;
    for (index in this.item_list) {
        var list_item = this.item_list[index];
        if (list_item == item) {
            return parseInt(index);
        }
    }
    return null;
};
YAHOO.zoeyplayer.Playlist.prototype.onInsertItem = function(item, index) {
    this.fireEvent('playlist_item_inserted', {
        item: item,
        index: index
    });
};
YAHOO.zoeyplayer.Playlist.prototype.removeItem = function(index) {
    removed_item = this.item_list.splice(index, 1)[0];
    this.onRemovePlayableItem(removed_item, index);
    return removed_item;
};
YAHOO.zoeyplayer.Playlist.prototype.clear = function() {
    while (this.hasItems()) {
        this.removeItem(this.item_list.length - 1);
    }
};
YAHOO.zoeyplayer.Playlist.prototype.onRemoveItem = function(item, index) {
    this.fireEvent('playlist_item_removed', {
        item: item,
        index: index
    });
};
YAHOO.lang.augmentProto(YAHOO.zoeyplayer.Playlist, YAHOO.util.EventProvider);


YAHOO.zoeyplayer.PlaybackManager = function() {
    this.soundplaying_count = 0;
    this.soundloading_count = 0;
    this.soundevent_interval = 4;

    this.createEvent('item_playback_started');
    this.createEvent('item_playback_status');
    this.createEvent('item_playback_stopped');
    this.createEvent('item_playback_paused');
    this.createEvent('item_playback_resumed');
    this.createEvent('item_playback_finished');
    this.createEvent('item_load_status');
    this.createEvent('item_load_finished');
    this.createEvent('item_metadata_received');

    var self = this;
    this.sound_events = this.initSoundEvents();
    this.current_item_idx = null;
    this.sound_count = 0;
    this.sound_objects = [];
    this.while_playing_count = 0;
    this.playlist = null;
    this.clear();
};
YAHOO.zoeyplayer.PlaybackManager.prototype.setPlaylist = function(playlist) {
    if (playlist != this.playlist) {
        this.stop();
        if (this.playlist != null) {
            this.playlist.unsubscribe('playlist_item_inserted', this.onInsertPlaylistItem);
            this.playlist.unsubscribe('playlist_item_removed', this.onRemovePlaylistItem);
        }

        this.current_item_idx = null;
        this.playlist = playlist;

        this.playlist.subscribe('playlist_item_inserted', this.onInsertPlaylistItem, this, true);
        this.playlist.subscribe('playlist_item_removed', this.onRemovePlaylistItem, this, true);
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.clear = function() {
    this.setPlaylist(new YAHOO.zoeyplayer.Playlist('Now Playing'));
    return this.playlist.clear();
};
YAHOO.zoeyplayer.PlaybackManager.prototype.stop = function() {
    if (this.current_sound_object != null) {
        soundManager.stop(this.current_sound_object.sID);
        if (!YAHOO.zoeyplayer.isTouchDevice) {
            soundManager.unload(this.current_sound_object);
        }
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.pause = function() {
    var item = this.getCurrentItem();
    if (item != null) {
        var sound_object = this.getSoundObject(item);
        sound_object.pause();
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.resume = function() {
    var item = this.getCurrentItem();
    if (item != null) {
        var sound_object = this.getSoundObject(item);
        sound_object.resume();
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.togglePause = function() {
    var item = this.getCurrentItem();
    if (item == null) {
        this.play();
    } else {
        var sound_object = this.getSoundObject(item);
        sound_object.togglePause();
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.play = function() {
    if (!this.playlist.hasItems()) {
        return;
    }
    if (this.current_item_idx == null) {
        this.current_item_idx = 0;
    }
    var item = this.getCurrentItem();
    if (item != null) {
        this.playItem(item);
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.previous = function() {
    this.current_item_idx -= 1;
    this.checkPlaylistBoundaries();

    if (this.current_item_idx == null && this.playlist.hasItems()) {
        this.current_item_idx = this.playlist.item_list.length - 1;
    }

    var item = this.getCurrentItem();
    if (item != null) {
        this.playItem(item);
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.next = function() {
    this.current_item_idx += 1;
    this.checkPlaylistBoundaries();
    if (this.current_item_idx == null && this.playlist.hasItems()) {
        this.current_item_idx = 0;
    }

    var item = this.getCurrentItem();
    if (item != null) {
        this.playItem(item);
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.isPlaying = function() {
    var item = this.getCurrentItem();
    if (item != null) {
        return item.isPlaying();
    }
    return false;
};
YAHOO.zoeyplayer.PlaybackManager.prototype.isPaused = function() {
    var item = this.getCurrentItem();
    if (item != null) {
        return item.isPaused();
    }
    return false;
};
YAHOO.zoeyplayer.PlaybackManager.prototype.getCurrentItem = function() {
    this.checkPlaylistBoundaries();
    if (this.current_item_idx == null) {
        return null;
    } else {
        return this.playlist.item_list[this.current_item_idx];
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.shouldAutoAdvance = function() {
    return true;
};
YAHOO.zoeyplayer.PlaybackManager.prototype.shouldRepeat = function() {
    return false;
};
YAHOO.zoeyplayer.PlaybackManager.prototype.shouldShuffle = function() {
    return false;
};
YAHOO.zoeyplayer.PlaybackManager.prototype.setItem = function(item) {
    if (this.current_sound_object != null) {
        soundManager.stop(this.current_sound_object.sID);
        if (!YAHOO.zoeyplayer.isTouchDevice) {
            soundManager.unload(this.current_sound_object.sID);
        }
        // Hack for SM2 HTML5 issues
        try {
            this.onSoundStop(this.current_sound_object);
        } catch(e) {
        }
    }

    var pls_index = this.playlist.getIndex(item);
    if (pls_index == null) {
        this.playlist.append(item);
        pls_index = this.playlist.item_list.length - 1;
    }
    this.current_item_idx = pls_index;
};
YAHOO.zoeyplayer.PlaybackManager.prototype.playItem = function(item) {
    this.setItem(item);
    var sound_object = this.getSoundObject(item);
    this.current_sound_object = sound_object;
    sound_object.play();
};
YAHOO.zoeyplayer.PlaybackManager.prototype.getSoundObject = function(item) {
    var item_sound_id = item.getSoundId();

    if (item_sound_id == null) {
        item_sound_id = 'sound' + this.sound_count++;
        item.setSoundId(item_sound_id);
    }

    var sound_object = this.sound_objects[item_sound_id];
    if (sound_object == null || sound_object == undefined) {
        sound_object = soundManager.createSound({
            id: item_sound_id,
            url: item.getPlaybackUrl(),
            onplay: this.sound_events.play,
            onstop: this.sound_events.stop,
            onpause: this.sound_events.pause,
            onresume: this.sound_events.resume,
            onfinish: this.sound_events.finish,
            whileloading: this.sound_events.whileloading,
            whileplaying: this.sound_events.whileplaying,
            onmetadata: this.sound_events.metadata,
            onload: this.sound_events.onload
        });
        sound_object.playable_item = item;
        // XXX: Circular references here
        this.sound_objects[item_sound_id] = sound_object;
        item.sound_object = sound_object;
        return sound_object;
    } else {
        return sound_object;
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.checkPlaylistBoundaries = function() {
    if (this.playlist.item_list.length <= 0) {
        this.current_item_idx = null;
    } else if (this.current_item_idx == null) {
        // do nothing
    } else {
        if (this.current_item_idx >= this.playlist.item_list.length) {
            this.current_item_idx = null;
        } else if (this.current_item_idx < 0) {
            this.current_item_idx = null;
        }
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.onInsertPlaylistItem = function(info) {
    if (this.current_item_idx != null && info.index <= this.current_item_idx) {
        this.current_item_idx += 1;
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.onRemovePlaylistItem = function(info) {
    if (this.current_item_idx != null && info.index < this.current_item_idx) {
        this.current_item_idx -= 1;
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.initSoundEvents = function() {
    var self = this;
    return {
        play: function() {
            self.while_playing_count = 0;
            self.onSoundPlay(this);
        },
        stop: function() {
            self.onSoundStop(this);
        },
        pause: function() {
            self.onSoundPause(this);
        },
        resume: function() {
            self.onSoundResume(this);
        },
        finish: function() {
            self.onSoundFinish(this);
        },
        onload: function() {
            self.onSoundLoad(this);
        },
        metadata: function() {
            self.onSoundMetaData(this);
        },
        whileloading: function() {
            self.whileSoundLoading(this);
        },
        whileplaying: function() {
            self.while_playing_count += 1;
            //if ((self.while_playing_count % 3)==0) {
                self.whileSoundPlaying(this);
            //}
        }
    };
};
YAHOO.zoeyplayer.PlaybackManager.prototype.onSoundPlay = function(sound) {
    sound.playable_item.onPlay(this);
    this.fireEvent('item_playback_started', {
        manager: this,
        sound: sound,
        playable_item: sound.playable_item
    });
};
YAHOO.zoeyplayer.PlaybackManager.prototype.onSoundStop = function(sound) {
    sound.playable_item.onStop(this);
    this.fireEvent('item_playback_stopped', {
        manager: this,
        sound: sound,
        playable_item: sound.playable_item
    });
};
YAHOO.zoeyplayer.PlaybackManager.prototype.onSoundPause = function(sound) {
    sound.playable_item.onPause(this);
    this.fireEvent('item_playback_paused', {
        manager: this,
        sound: sound,
        playable_item: sound.playable_item
    });
};
YAHOO.zoeyplayer.PlaybackManager.prototype.onSoundResume = function(sound) {
    sound.playable_item.onResume(this);
    this.fireEvent('item_playback_resumed', {
        manager: this,
        sound: sound,
        playable_item: sound.playable_item
    });
};
YAHOO.zoeyplayer.PlaybackManager.prototype.onSoundFinish = function(sound) {
    sound.playable_item.onFinish(this);
    this.fireEvent('item_playback_finished', {
        manager: this,
        sound: sound,
        playable_item: sound.playable_item
    });

    if (this.shouldAutoAdvance()) {
        if (this.shouldShuffle()) {
            // TODO Implement shuffle;
        } else {
            this.current_item_idx++;
            this.checkPlaylistBoundaries();
            if (this.current_item_idx == null && this.shouldRepeat()) {
                this.current_item_idx = 0;
            } 
            var item = this.getCurrentItem();
            if (item == null) {
                this.stop();
            } else {
                this.playItem(item);
            }
        }
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.onSoundLoad = function(sound) {
    sound.playable_item.onLoad(this);
    this.fireEvent('item_load_finished', {
        manager: this,
        sound: sound,
        playable_item: sound.playable_item
    });
};
YAHOO.zoeyplayer.PlaybackManager.prototype.onSoundMetaData = function(sound) {
    sound.playable_item.onMetaData(this);
    this.fireEvent('item_metadata_received', {
        manager: this,
        sound: sound,
        playable_item: sound.playable_item
    });
};
YAHOO.zoeyplayer.PlaybackManager.prototype.whileSoundLoading = function(sound) {
    this.soundloading_count += 1;
    if ((this.soundloading_count % (this.soundevent_interval*2)) == 0) {
        this.fireEvent('item_load_status', {
            manager: this,
            sound: sound,
            playable_item: sound.playable_item
        });
    }
};
YAHOO.zoeyplayer.PlaybackManager.prototype.whileSoundPlaying = function(sound) {
    this.soundplaying_count += 1;
    if ((this.soundplaying_count % this.soundevent_interval) == 0) {
        this.fireEvent('item_playback_status', {
            manager: this,
            sound: sound,
            playable_item: sound.playable_item
        });
    }
};
YAHOO.lang.augmentProto(YAHOO.zoeyplayer.PlaybackManager, YAHOO.util.EventProvider);


YAHOO.zoeyplayer.init = function() {
    YAHOO.zoeyplayer.playback = new YAHOO.zoeyplayer.PlaybackManager();
};


soundManager.onload = function() {
    YAHOO.util.Dom.addClass(document.body, 'sm2-load-success');
    YAHOO.zoeyplayer.sm2_load_success.fire(null);
}
soundManager.onerror = function() {
    if (soundManager.canPlayMIME('audio/mpeg')) {
        // HTML5 Support
        soundManager.onload();
    } else {
        YAHOO.util.Dom.addClass(document.body, 'sm2-load-failure');
        YAHOO.zoeyplayer.sm2_load_failure.fire(null);
    }
}



