/* BEGIN: common/constants */

var VISITOR = 1,
    USER    = 2;

var EPISODE_DESCRIPTION_LINES = 3,
    EPISODE_DESCRIPTION_HEIGHT = EPISODE_DESCRIPTION_LINES * 16,
    
    SHOW_DESCRIPTION_LINES = 5,
    SHOW_DESCRIPTION_HEIGHT = SHOW_DESCRIPTION_LINES * 16;
    
var MORE_ICON       = "/images/common/blue_more.gif",
    LESS_ICON = "/images/common/blue_less.gif";

var PLAYLIST_INFERRED = "/images/playlist/playlist_inferred.gif",
    GREY_PLAYLIST_INFERRED = "/images/playlist/grey_playlist_inferred.gif",
    PLAYLIST_VALID = "/images/playlist/playlist_valid.png";
    
var SORT_ALPHA      = "alpha",
    SORT_PUB_DATE   = "pubdate",
    SORT_CHANNEL    = "channel";

var MAX_SEARCH_EPISODES = 3;

var ALL_CHANNEL_NAME = "All (Mix)";
var ALL_CHANNEL_SLUG = "__all_2__";

var NEW24H_CHANNEL_NAME = "New (24 hours)";
var NEW24H_CHANNEL_SLUG = "__new24h__";

var NEW7D_CHANNEL_NAME = "New (7 days)";
var NEW7D_CHANNEL_SLUG = "__new7d__";

var FAVORITES_CHANNEL_NAME = "Favorites";
var FAVORITES_CHANNEL_SLUG = "__favorites__";


/***************************************************************
 * Custom jQuery
 ***************************************************************/ 
 
$.fn.disable = function() {
    return this.each(function() {
        if(typeof this.disabled != "undefined") this.disabled = true;
    });
}

$.fn.enable = function() {
    return this.each(function() {
        if(typeof this.disabled != "undefined") this.disabled = false;
    });
}


$.fn.isVisible = function() {
    return this.css('display') != ("none" || "");
}

function pluralize(_count) {

    return (_count != 1)  ? "s" : "";
}

function clone(what) {
    for (i in what) {
        if (typeof what[i] == 'object') {
            this[i] = new clone(what[i]);
        }
        else
            this[i] = what[i];
    }
}

function isSpecialChannel(_slug) {

    return( _slug == ALL_CHANNEL_SLUG ||
			_slug == FAVORITES_CHANNEL_SLUG ||
			_slug == NEW24H_CHANNEL_SLUG ||
			_slug == NEW7D_CHANNEL_SLUG );
}

function isNullOrEmpty(_val) {
	return (_val == null || _val == undefined || _val == "");
}

/* BEGIN: common/mediaplayer_controller */

var MEDIA_PLAYER_WIDTH = 800;
var MEDIA_PLAYER_HEIGHT = 526;

var MediaPlayer = {
	popupEpisode: function(episode, channel) {
	    var url = '';
	    
	    if (channel) {
	        url = '/Player/Channel/' + channel + '/Episode/' + episode;
	    } else {
	        url = '/Player/Episode/' + episode;
	    }
	    
	    popup(url, MEDIA_PLAYER_WIDTH, MEDIA_PLAYER_HEIGHT, 'MediaflyPlayer');
	},
	
	popupShowEpisode: function(episode, show) {
		popup('/Player/Show/' + show + "/Episode/" + episode, MEDIA_PLAYER_WIDTH, MEDIA_PLAYER_HEIGHT, 'MediaflyPlayer');
	},
	
	popupFeed: function(feed) {
		popup('/Player/Show/' + feed, MEDIA_PLAYER_WIDTH, MEDIA_PLAYER_HEIGHT, 'MediaflyPlayer');
	},
	
	popupPlaylist: function() {
	    popup('/Player', MEDIA_PLAYER_WIDTH, MEDIA_PLAYER_HEIGHT, 'MediaflyPlayer');
	},
	
	popupChannel: function(channel) {
	    popup('/Player/Channel/' + channel, MEDIA_PLAYER_WIDTH, MEDIA_PLAYER_HEIGHT, 'MediaflyPlayer');
	},
	
	popupPublisherEpisode: function(episodeUrl) {
	    popup('http://www.mediafly.com/MediaPlayer/ExternalLink/' + episodeUrl, MEDIA_PLAYER_WIDTH, MEDIA_PLAYER_HEIGHT, 'player'); 
	},
	
	popupSegment: function(segment) {
	    popup('/MediaPlayer/Default.aspx?s=publisher&p=0&c=0&segment=' + segment, MEDIA_PLAYER_WIDTH, MEDIA_PLAYER_HEIGHT, 'player');
	},
	
	popupMasterAsset: function(originalUrl) {
        popup('http://www.mediafly.com/MediaPlayer/ExternalLink/' + originalUrl, MEDIA_PLAYER_WIDTH, MEDIA_PLAYER_HEIGHT, 'player');
	}
};

/* BEGIN: common/rating_controller */

/***************************************************************
 * Ratings
 ***************************************************************/ 
 
 var HUD_RATING_IMAGE = "/images/rollover/grey_star.gif";

function RatingController()
{
    popupController.init();

    this.ratingTemplate = TrimPath.parseDOMTemplate("episodeRatingTemplate");
}

RatingController.prototype.init = function () {
    this.bindListeners();
}

RatingController.prototype.bindListeners = function () {

    // TODO:  There is probably a better way of doiung this any unbinding all existing favorite bindings
    $('.favoriteicon').unbind('click');
    $('.removemyrating').unbind('click');

    $('.myrating').bind('click', function () {

        var value = $(this).attr('value');
        var type = $(this).attr('type');
        var slug = $(this).attr('slug');

        if (type == EPISODE)
            ratingController.rateEpisode(slug, value);
        else if (type == SHOW)
            ratingController.rateShow(slug, value);
    });

    $('.removemyrating').bind('click', function () {

        var type = $(this).attr('type');
        var slug = $(this).attr('slug');

        if (type == EPISODE)
            ratingController.removeEpisodeRating(slug);
        else if (type == SHOW)
            ratingController.removeShowRating(slug);
    });
}

RatingController.prototype.updateRatings = function(_object) {

    if(!_object) return;

    $('.myrating[type=' + _object.Type + '][slug=' + _object.Slug +']').each(function (n) {
    
        if(_object.MyRating > n) {
            $(this).css('background', 'url(/images/common/yellow_star.gif)');
        } else {
            $(this).css('background', '');
        }
    });

    if (_object.MyRating > 0) {
        $('.removemyrating[type=' + _object.Type + '][slug=' + _object.Slug + ']').show();
    } else {
        $('.removemyrating[type=' + _object.Type + '][slug=' + _object.Slug + ']').hide();
    }

    $('.communityratings[type=' + _object.Type + '][slug=' + _object.Slug + ']').css('width', (_object.AvgRating * 14));

    if (_object.RatingsCount > 0) {

        $('.hudratings[type=' + _object.Type + '][slug=' + _object.Slug + ']').show();
        $('.ratingsvalue[type=' + _object.Type + '][slug=' + _object.Slug + ']').html(_object.RatingValue);

        $('.ratingscount[type=' + _object.Type + '][slug=' + _object.Slug + ']').html('(' + _object.RatingsCount + ')').show();
    } else {

        $('.hudratings[type=' + _object.Type + '][slug=' + _object.Slug + ']').hide();
        $('.ratingscount[type=' + _object.Type + '][slug=' + _object.Slug + ']').html('(' + _object.RatingsCount + ')').hide();
    }
}

RatingController.prototype.rateShow = function(_showSlug, _rating) {

    var params = {
        doRefresh : false,
        onSuccess : function(_result) { ratingController.ratingSuccess(_result, "Show") },
        method : '/WebServices/RatingService_v1_0.asmx/AddShowRating',
        args : {showSlug : _showSlug, rating : _rating}
    };
    
    webService.invoke(params);
}

RatingController.prototype.rateEpisode = function(_episodeSlug, _rating) {

    var params = {
        doRefresh : false,
        onSuccess : function(_result) { ratingController.ratingSuccess(_result, "Episode") },
        method : '/WebServices/RatingService_v1_0.asmx/AddEpisodeRating',
        args : {episodeSlug : _episodeSlug, rating : _rating}
    };
    
    webService.invoke(params);
}

RatingController.prototype.removeEpisodeRating = function(_episodeSlug) {

    var params = {
        doRefresh : false,
        onSuccess : function(_result) { ratingController.ratingSuccess(_result, "Episode") },
        method : '/WebServices/RatingService_v1_0.asmx/RemoveEpisodeRating',
        args : {episodeSlug : _episodeSlug}
    };
    
    webService.invoke(params);
}

RatingController.prototype.removeShowRating = function(_showSlug) {

    var params = {
        doRefresh : false,
        onSuccess : function(_result) { ratingController.ratingSuccess(_result, "Show") },
        method : '/WebServices/RatingService_v1_0.asmx/RemoveShowRating',
        args : {showSlug : _showSlug}
    };
    
    webService.invoke(params);
}

RatingController.prototype.ratingSuccess = function(_result, _type) {

    if(_type == "Show") {
        var object = pageModel.getShow(_result.Slug);
    } else if(_type == "Episode") {
        var object = pageModel.getEpisode(_result.Slug);
    }
    
    object.MyRating = _result.MyRating;
    object.AvgRating = _result.AvgRating;
    object.RatingValue = _result.RatingValue;
    object.RatingsCount = _result.RatingsCount;
    
    this.updateRatings(object);
}

/* BEGIN: common/favorite_controller */

/***************************************************************
 * Favorites
 ***************************************************************/ 

function FavoriteController()
{
    popupController.initPopup("favoriteLoginPopupTemplate");
    popupController.init();
}

FavoriteController.prototype.init = function (_globalPageVModel) {
    this.pageModel = _globalPageVModel;

    this.bindListeners();
}

FavoriteController.prototype.bindListeners = function () {

    // TODO:  There is probably a better way of doiung this any unbinding all existing favorite bindings
    $('.favoriteicon').unbind('click');

    $('.favoriteicon').bind('click', function () {

        var type = $(this).attr('type');
        var slug = $(this).attr('slug');

        if (type == EPISODE)
            favoriteController.toggleEpisodeFavorite(slug);
        else if (type == SHOW)
            favoriteController.toggleShowFavorite(slug);
    });
}

FavoriteController.prototype.updateFavorite = function(_object) {

    if(!_object) return;
    
    if(_object.IsFavorite) {
        $('.favoriteicon[type=' + _object.Type + '][slug=' + _object.Slug + ']').css('background-image', 'url(/images/common/red_heart.gif)');
    } else {
        $('.favoriteicon[type=' + _object.Type + '][slug=' + _object.Slug + ']').css('background-image', 'url(/images/common/grey_heart.gif)');
    }
}

FavoriteController.prototype.toggleEpisodeFavorite = function(_episodeSlug) {

    if(this.pageModel.UserType == USER) {
        var params = {
            doRefresh : false,
            onSuccess : function(_result) { favoriteController.favoriteSuccess(_result, EPISODE) },
            method : '/WebServices/FavoritesService_v1_0.asmx/ToggleFavoriteEpisode',
            args : {episodeSlug : _episodeSlug}
        };
        
        webService.invoke(params);

    } else {
    
        popupController.displayPopupX("favoriteLoginPopupTemplate", this.pageModel);
    }
}

FavoriteController.prototype.toggleShowFavorite = function(_showSlug) {

    if(this.pageModel.UserType == USER) {
        var params = {
            doRefresh : false,
            onSuccess : function(_result) { favoriteController.favoriteSuccess(_result, SHOW) },
            method : '/WebServices/FavoritesService_v1_0.asmx/ToggleFavoriteShow',
            args : {showSlug : _showSlug}
        };
        
        webService.invoke(params);

    } else {
    
        popupController.displayPopupX("favoriteLoginPopupTemplate", this.pageModel);
    }
}

FavoriteController.prototype.favoriteSuccess = function (_result, _type) {

    if (_type == SHOW) {
        var show = pageModel.getShow(_result.Slug);
        show.IsFavorite = _result.IsFavorite;
        show.IsInferred = true;
        this.updateFavorite(show);

    } else if (_type == EPISODE) {
        var episode = pageModel.getEpisode(_result.Slug);
        episode.IsFavorite = _result.IsFavorite;
        episode.Show.IsInferred = true;
        this.updateFavorite(episode);

        var show = episode.Show;
    }

    subscriptionController.updateEpisodeCount(show);
    headerController.updateHeader();
}

/* BEGIN: common/subscription_popup_view */

var TRASH_ICON              = "/images/common/trashcan.gif",
	TRASH_INACTIVE_ICON     = "/images/common/trashcan_inactive.gif",
    ADD_ICON                = "/images/common/add.gif",
    PREFS_ICON              = "/images/common/syncprefs-bw.gif",
    CHANNEL_ICON            = "/images/common/channel_changer.gif",
    CHANNEL_INACTIVE_ICON   = "/images/common/channel_changer_inactive.gif";
    
var NEW_CHANNEL_ICON		= "/images/common/folder-new.gif";
    
var DAYS_TYPE_UNKNOWN = 0,
    DAYS_TYPE_ALLDAYS = 1,
    DAYS_TYPE_WEEKDAYS = 2,
    DAYS_TYPE_SMARTDAYS = 3;

var UNKNOWN_FLAG = 0,
    AUDIO_FLAG = 1,
    VIDEO_FLAG = 2,
    AUDIO_VIDEO_FLAG = 3;

var INT_MAX = 2900000;  // real Int.Max == 2918512

function SubscriptionPopupView()
{
    this.channelItemsTemplate   = TrimPath.parseDOMTemplate("channelItemsTemplate");
    this.channelItemTemplate    = TrimPath.parseDOMTemplate("channelItemTemplate");
    this.treeviewTemplate		= TrimPath.parseDOMTemplate("treeviewTemplate");

    popupController.initPopup("channelPrefsTemplate");
    popupController.initPopup("showPrefsTemplate");
    popupController.initPopup("episodePrefsTemplate");

    popupController.initPopup("changeChannelTemplate");

    popupController.initPopup("removeChannelItemsTemplate");
    popupController.initPopup("removeChannelTemplate");

    popupController.initPopup("renameChannelTemplate");

    popupController.initPopup("firstSubscriptionTemplate");
    
    popupController.initPopup("searchSubscriptionTemplate");
    
    popupController.initPopup("requiresLoginTemplate");    

    popupController.init();
}

SubscriptionPopupView.prototype.init = function(_globalSubscriptionModel) {

    this.globalSubscriptionModel = _globalSubscriptionModel;
}

/***************************************************************
 * Show Subscriptions Popup
 ***************************************************************/ 

SubscriptionPopupView.prototype.requiresLoginPopup = function(_showModel, _device) {

	var obj = {
		Title : _showModel.Title,
		Device : (_device == ITUNES) ? "iTunes" : "Zune",
		CurrentUrl : pageController.getCurrentUrl()
	};

	popupController.open("requiresLoginTemplate", obj);
}


/***************************************************************
 * Show Subscriptions Popup
 ***************************************************************/

SubscriptionPopupView.prototype.updateShowSubscriptionPopup = function (_show) {

    if (_show.SubscriptionModel == null)
        _show.SubscriptionModel = this.globalSubscriptionModel;

    popupController.open("showPrefsTemplate", _show);


    // Media Types
    var mediaTypeString = "";
    if (_show.SubscriptionModel.MediaTypes != null) {

        $('#mediaTypesOption').find('.prefs').show();
        this.setMediaTypeControl(_show.SubscriptionModel.MediaTypes)
        mediaTypeString = this.generateMediaTypeString(this.globalSubscriptionModel);

    } else {

        this.setMediaTypeControl(this.globalSubscriptionModel.RolledUpMediaTypes)

        $('#mediaTypesOption').find('.rolledUpPrefs').show();
        mediaTypeString = this.generateMediaTypeString(_show.SubscriptionModel);
    }
    $('#mediaTypesOption').find('.rolledUpPrefs').append(mediaTypeString);


    // # of episodes
    var maxEpisodesString = "";
    if (_show.SubscriptionModel.MaxEpisodes != null) {

        $('#maxEpisodesOption').find('.prefs').show();
        this.setMaxEpisodesControl(_show.SubscriptionModel.MaxEpisodes);
        maxEpisodesString = this.generateMaxEpisodesString(this.globalSubscriptionModel);

    } else {

        this.setMaxEpisodesControl(this.globalSubscriptionModel.RolledUpMaxEpisodes);

        $('#maxEpisodesOption').find('.rolledUpPrefs').show();
        maxEpisodesString = this.generateMaxEpisodesString(_show.SubscriptionModel);
    }
    $('#maxEpisodesOption').find('.rolledUpPrefs').append(maxEpisodesString);


    // # of days
    var maxDaysString = "";
    if (_show.SubscriptionModel.DaysType != null) {

        $('#maxDaysOption').find('.prefs').show();
        this.setMaxDaysControl(_show.SubscriptionModel.MaxDays, _show.SubscriptionModel.DaysType);
        maxDaysString = this.generateMaxDaysString(this.globalSubscriptionModel);

    } else {

        this.setMaxDaysControl(this.globalSubscriptionModel.RolledUpMaxDays, this.globalSubscriptionModel.RolledUpDaysType);

        $('#maxDaysOption').find('.rolledUpPrefs').show();
        maxDaysString = this.generateMaxDaysString(_show.SubscriptionModel);
    }
    $('#maxDaysOption').find('.rolledUpPrefs').append(maxDaysString);


    var minExperienceString = "";
    if (_show.SubscriptionModel.MinExperience != null) {

        $('#minExperienceOption').find('.prefs').show();
        this.setMinExperienceControl(_show.SubscriptionModel.MinExperience);
        minExperienceString = this.generateMinExperienceString(this.globalSubscriptionModel);

    } else {

        this.setMinExperienceControl(this.globalSubscriptionModel.RolledUpMinExperience);

        $('#minExperienceOption').find('.rolledUpPrefs').show();
        minExperienceString = this.generateMinExperienceString(_show.SubscriptionModel);
    }
    $('#minExperienceOption').find('.rolledUpPrefs').append(minExperienceString);

    $('#inactiveSubscriptionCheckbox').attr('checked', _show.SubscriptionModel.SubscriptionInactive);


    this.bindShowListeners();
}

SubscriptionPopupView.prototype.bindShowListeners = function() {

    $('input.maxDaysRadio').bind('click', function(_event) {

        if($(this).hasClass('limit')) {
            $('input#maxDaysText').enable();
            $('#daysTypeDropdown').enable();
        } else {
            $('input#maxDaysText').disable();
            $('#daysTypeDropdown').disable();
        }
    });
    
    $('input.maxEpisodesRadio').bind('click', function(_event) {

        if($(this).hasClass('limit')) {
            $('#maxEpisodesText').enable();
        } else {
            $('#maxEpisodesText').disable();
        }
    });
}


/***************************************************************
 * Show Preference Controls
 ***************************************************************/ 

SubscriptionPopupView.prototype.setMediaTypeControl = function(_mediaTypes) {

    $('#includeAudio').attr('checked', ((_mediaTypes & AUDIO_FLAG) != 0))
    $('#includeVideo').attr('checked', ((_mediaTypes & VIDEO_FLAG) != 0))
}

SubscriptionPopupView.prototype.setMaxEpisodesControl = function(_maxEpisodes) {

    if(_maxEpisodes > 0) {
        $('input.maxEpisodesRadio.limit').attr('checked', true);
        $('input#maxEpisodesText').val(_maxEpisodes).enable();
    } else {
        $('input.maxEpisodesRadio.noLimit').attr('checked', true);
        $('input#maxEpisodesText').disable();            
    }
}

SubscriptionPopupView.prototype.setMaxDaysControl = function(_maxDays, _daysType) {

    if(_maxDays > 0) {

        $('input.maxDaysRadio.limit').attr('checked', true);
        $('input#maxDaysText').val(_maxDays).enable();
        $('#daysTypeDropdown').val(_daysType);
        
    } else {
    
        $('input.maxDaysRadio.noLimit').attr('checked', true);
        $('input#maxDaysText').disable();
        $('#daysTypeDropdown').disable();
    }
}

SubscriptionPopupView.prototype.setMinExperienceControl = function(_minExperience) {
    $('input#minExperienceText').val(_minExperience);
}


/***************************************************************
 * Show Getters
 ***************************************************************/ 

SubscriptionPopupView.prototype.getMediaTypes = function() {

    if($('#mediaTypesOption').find('.prefs').css('display') == 'none') {
        return null;
    }

    var mediaType = UNKNOWN_FLAG;
    if($("input#includeAudio").attr("checked")) {
        mediaType |= AUDIO_FLAG;
    }
    if($("input#includeVideo").attr("checked")) {
        mediaType |= VIDEO_FLAG;
    }
    
    return mediaType;
}

SubscriptionPopupView.prototype.getMaxEpisodesText = function() {

    if($('#maxEpisodesOption').find('.prefs').css('display') == 'none') {
        return null;
    }
    
    return $("#maxEpisodesText").val().trim();
}

SubscriptionPopupView.prototype.getMaxEpisodes = function() {

    if($('#maxEpisodesOption').find('.prefs').css('display') == 'none') {
        return null;
    }

    if($('input.maxEpisodesRadio:checked').hasClass('limit')) {
        var maxEpisodes = this.getMaxEpisodesText();
        return (maxEpisodes == "") ? 0 : parseInt(maxEpisodes);
    } else {
        return 0;
    }
}

SubscriptionPopupView.prototype.getMaxDaysText = function() {

    if($('#maxDaysOption').find('.prefs').css('display') == 'none') {
        return null;
    }

    if($('input.maxDaysRadio:checked').hasClass('limit')) {
        return $('input#maxDaysText').val().trim();
    } else {
        return "0";
    }
}

SubscriptionPopupView.prototype.getMaxDays = function() {

    if($('#maxDaysOption').find('.prefs').css('display') == 'none') {
        return null;
    }

    return parseInt(this.getMaxDaysText());
}

SubscriptionPopupView.prototype.getDaysType = function() {

    if($('#maxDaysOption').find('.prefs').css('display') == 'none') {
        return null;
    }

    if($('input.maxDaysRadio:checked').hasClass('limit') > 0) {    
        var index = $('#daysTypeDropdown')[0].selectedIndex;
        return index+1;
    } else {
        return DAYS_TYPE_ALLDAYS;
    }
}

SubscriptionPopupView.prototype.getMinExperienceText = function() {

    if($('#minExperienceOption').find('.prefs').css('display') == 'none') {
        return null;
    }

    return $("#minExperienceText").val().trim();
}

SubscriptionPopupView.prototype.getMinExperience = function() {

    if($('#minExperienceOption').find('.prefs').css('display') == 'none') {
        return null;
    }

    var minExperience = this.getMinExperienceText();
    return parseInt(minExperience);
}


/***************************************************************
 * Show Preference Strings
 ***************************************************************/ 

SubscriptionPopupView.prototype.generateMediaTypeString = function(_subscription) {

    var mediaTypesHtml = "Include ";
        
    if(_subscription.RolledUpMediaTypes == AUDIO_VIDEO_FLAG) {
        mediaTypesHtml += "audio and video.";    
    } else if(_subscription.RolledUpMediaTypes == AUDIO_FLAG) {
        mediaTypesHtml += "audio.";
    } else if(_subscription.RolledUpMediaTypes == VIDEO_FLAG) {
        mediaTypesHtml += "video.";
    }
        
    return mediaTypesHtml;
}

SubscriptionPopupView.prototype.generateMaxEpisodesString = function(_subscription) {

    var maxEpisodesHtml = "";
    if(_subscription.RolledUpMaxEpisodes > 0) {
        maxEpisodesHtml = "Include up to " + _subscription.RolledUpMaxEpisodes + " episode" + pluralize(_subscription.RolledUpMaxEpisodes) + ".";
    } else {
        maxEpisodesHtml = "Include the maximum number of episodes.";
    }
    return maxEpisodesHtml;
}

SubscriptionPopupView.prototype.generateMaxDaysString = function(_subscription) {

    var maxDaysHtml = "";    
    if(_subscription.RolledUpMaxDays > 0) {
    
        maxDaysHtml = "Let episodes expire after " + _subscription.RolledUpMaxDays + " ";
                        
        switch(_subscription.RolledUpDaysType)
        {
        case DAYS_TYPE_ALLDAYS:
            maxDaysHtml += "day";
            break;
            
        case DAYS_TYPE_WEEKDAYS:
            maxDaysHtml += "week day";
            break;
            
        case DAYS_TYPE_SMARTDAYS:
            maxDaysHtml += "smart day";
            break;
        }
        
        maxDaysHtml += pluralize(_subscription.RolledUpMaxDays) + ".";
        
    } else {
        
        maxDaysHtml = "Do not let episodes expire by date.";
    }
    
    return maxDaysHtml;
}

SubscriptionPopupView.prototype.generateMinExperienceString = function(_subscription) {
    return "Remove an episode after listening to " + _subscription.RolledUpMinExperience + "%.";
}

SubscriptionPopupView.prototype.getInactiveCheckValue = function() {
    return $('#inactiveSubscriptionCheckbox').attr('checked');
}

/***************************************************************
 * Edit Prefs
 ***************************************************************/ 

SubscriptionPopupView.prototype.editPrefs = function(_id) {
    $('#' + _id).find('.rolledUpPrefs').hide();
    $('#' + _id).find('.prefs').show();
}

SubscriptionPopupView.prototype.removePrefs = function(_id) {
    $('#' + _id).find('.rolledUpPrefs').show();
    $('#' + _id).find('.prefs').hide();
}


/***************************************************************
 * Validators
 ***************************************************************/ 
 
SubscriptionPopupView.prototype.isValid = function() {

    var maxEpisodes = this.getMaxEpisodesText();
    var maxDays = this.getMaxDaysText();
    var minExperience = this.getMinExperienceText();
    
    var regExp = new RegExp("^[0-9]+$");
    
    if(maxEpisodes != null && $('input.maxEpisodesRadio:checked').hasClass('limit')) {
        if(!regExp.test(maxEpisodes)) {
            alert("Please enter a valid number of episodes");
            return false;
        }
    }
    
    if(maxDays != null && $('input.maxDaysRadio:checked').hasClass('limit')) {
        if(!regExp.test(maxDays)) {
            alert("Please enter a valid number of days");
            return false;
        }
    }
    
    if(minExperience != null) {
        if((minExperience == "" || !regExp.test(minExperience))) {
            alert("Please enter a valid number between 1 and 100 for experience");
            return false;
        }
        minExperience = parseInt(minExperience);
        if(minExperience < 1 || minExperience > 100) {
            alert("Please enter a valid number between 1 and 100 for experience");
            return false;
        }
    }
    
    return true;
}

SubscriptionPopupView.prototype.subscriptionStateChangedForShow = function(_show) {

    var inactive = this.getInactiveCheckValue();
    if(_show.SubscriptionModel.SubscriptionInactive != inactive) {
        return true;
    }

    return false;
}


/***************************************************************
 * Channel Management
 ***************************************************************/ 

SubscriptionPopupView.prototype.populateFolders = function (_html, _channelModel, _index) {

    var checkboxMargin = 47 + (_index * 16);

    var nodeClass = (_channelModel.SubChannels.length > 0) ? "folder" : "folder empty";
    _html.append("<li slug='" + _channelModel.Slug + "'><span class='" + nodeClass + "'><div style='float: left; margin-left: -" + checkboxMargin + "px; margin-top: -1px;'><input type='checkbox' slug='" + _channelModel.Slug + "' /></div><div slug='" + _channelModel.Slug + "' class='channel'>" + _channelModel.Name + "</div></span>");
    if (_channelModel.SubChannels.length > 0) {
        _html.append("<ul slug='" + _channelModel.Slug + "'>");
        for (var i = 0; i < _channelModel.SubChannels.length; i++) {
            this.populateFolders(_html, _channelModel.SubChannels[i], _index + 1);
        }
        _html.append("</ul>");
    }
    _html.append("</li>");
}

SubscriptionPopupView.prototype.populateChannelTreeview = function (_checkedChannels, _openChannels) {

    var treeviewHtml = this.treeviewTemplate.process();
    $("#treeview").html(treeviewHtml);

    var channelModels = pageModel.getMyRootChannelModels();

    var rootChannelName = "My Channels";

    var html = new StringBuilder();
    html.append("<li class='open'><span class='folder'><div slug='' class='channel rootchannel'>" + rootChannelName + "</div></span>");
    html.append("<ul class=''>");
    for (var i = 0; i < channelModels.length; i++) {
        this.populateFolders(html, channelModels[i], 0);
    }
    html.append("</ul>");
    html.append("</li>");

    $("#browser").html(html.toString());

    if (_checkedChannels) {

        for (var i = 0; i < _checkedChannels.length; i++) {

            if (_checkedChannels[i] == null)
                continue;

            var channelModel = pageModel.getChannelModel(_checkedChannels[i].Slug);
            if (channelModel) {
                while (channelModel && channelModel.ParentChannelSlug) {
                    $('#browser').find('li[slug=' + channelModel.ParentChannelSlug + ']').addClass('open');
                    channelModel = pageModel.getChannelModel(channelModel.ParentChannelSlug);
                }
            }

            $('input[slug=' + _checkedChannels[i].Slug + ']').attr('checked', 'checked');
        }
    }

    if (_openChannels) {

        for (var i = 0; i < _openChannels.length; i++) {

            if (_openChannels[i] == null)
                continue;

            var channelModel = pageModel.getChannelModel(_openChannels[i].Slug);
            if (channelModel) {
                $('#browser').find('li[slug=' + channelModel.Slug + ']').addClass('open');
            }
        }
    }

    $("#browser").treeview({ collapsed: true });

    this.selectTreeItem($("#browser").find(".channel:first"));
}

SubscriptionPopupView.prototype.populateSubscriptionList = function(_subscriptionBindingModels) {

	if (_subscriptionBindingModels.length == 0)
		return;
		
	var channelItemsHtml = this.channelItemsTemplate.process();
	$("#channelItemsContainer").html(channelItemsHtml);

	var html = new StringBuilder();
	for (var i=0; i < _subscriptionBindingModels.length; i++) {
		var channelItem = this.channelItemTemplate.process(_subscriptionBindingModels[i]);
		html.append(channelItem);
	}
	$("#channelItems").html(html.toString());
	
	$(".channelItemContainer:odd").addClass('oddChannelItems');
	
	$(".channelItem").bind("click", function(_event){
	
		var checked = $(this).attr('checked');
		if(!checked) {
			$("#selectAll").attr('checked', '');
		}
	});
	
	$("#selectAll").bind("click", function(_event){
		
		var checked = $(this).attr('checked');
		$(".channelItem").each(function(){
			$(this).attr('checked', checked);
		});
	});
}

SubscriptionPopupView.prototype.contextMenuRenameChannel = function() {

	var channelText = $('.selectedChannel').text();
	$('.selectedChannel').html("<input type='text' value='" + channelText + "' class='channelNameInput' />");
	$('.channelNameInput').bind('blur change', function(_event) {
	
		$('.channelNameInput').unbind('blur change');
		
		var channelText = $('.channelNameInput').val();
		$('.selectedChannel').html(channelText);
		
		subscriptionController.submitContextMenuRenameChannel();
	});
	
	$('.channelNameInput').focus().select();
}

SubscriptionPopupView.prototype.bindChannelListeners = function() {

	$("#browser").find("input[type=checkbox]").bind("click", function(_event) {
		_event.stopPropagation();
    });

    $("#browser").find(".channel").bind("click", function (_event) {
		_event.stopPropagation();
		subscriptionController.subscriptionPopupView.selectTreeItem($(this));
	});
	
	$("#browser li").bind("click", function(_event) {
		_event.stopPropagation();
		subscriptionController.subscriptionPopupView.selectTreeItem($(this).find('span .channel:first'));
	});
	
	var rootChannelMenu = [
		{'Create New Channel':{
				onclick : subscriptionController.contextMenuCreateChannel,
				icon : NEW_CHANNEL_ICON
			}
		}
	];
	
	$("#browser").find(".rootchannel").contextMenu(rootChannelMenu,{theme:'vista'});
	$("#browser").find(".rootchannel").bind('contextmenu', function(_event) {
		$(this).trigger('click');
	});

	
	var channelMenu = [
		{'Create New Channel':{
				onclick : subscriptionController.contextMenuCreateChannel,
				icon : NEW_CHANNEL_ICON
			}
		},
		$.contextMenu.separator,
		{'Rename Channel':{
				onclick : subscriptionController.contextMenuRenameChannel,
				icon : CHANNEL_ICON
			}
		},
		$.contextMenu.separator,
		{'Remove Channel':{
				onclick : subscriptionController.contextMenuRemoveChannel,
				icon : TRASH_ICON
			}
		}
	];

	$("#browser").find(".channel").not(".rootchannel").contextMenu(channelMenu,{theme:'vista'});
	$("#browser").find(".channel").bind('contextmenu', function(_event) {
		$(this).trigger('click');
	});
}

SubscriptionPopupView.prototype.contextMenuCreateChannel = function (_checkedChannels, _openChannelModels) {

    var parentChannelSlug = this.getSelectedChannelSlug();

    var channelModel = {
        Name: "New Channel",
        Slug: "__newchannel__",
        Position: null,
        ParentChannelSlug: parentChannelSlug,
        SubChannels: []
    };

    pageModel.addChannelModel(channelModel, parentChannelSlug);

    var parentChannelModel = pageModel.getChannelModel(parentChannelSlug);
    _openChannelModels.push(parentChannelModel);

    this.populateChannelTreeview(_checkedChannels, _openChannelModels);
    this.bindChannelListeners();

    this.selectTreeItem($("#browser").find(".channel[slug=__newchannel__]"));
    this.contextMenuRenameChannel();
}

SubscriptionPopupView.prototype.selectTreeItem = function(_item) {

	$('.channel').removeClass('selectedChannel');

	_item.addClass('selectedChannel');
	
	if (_item.hasClass('rootchannel')) {
	
		$("#renamechannel").removeClass('activerenamechanneloption');
		$("#removechannel").removeClass('activeremovechanneloption');
		
		$("#renamechannel").addClass('inactiverenamechanneloption');
		$("#removechannel").addClass('inactiveremovechanneloption');
	
	} else {
	
		$("#renamechannel").removeClass('inactiverenamechanneloption');
		$("#removechannel").removeClass('inactiveremovechanneloption');
		
		$("#renamechannel").addClass('activerenamechanneloption');
		$("#removechannel").addClass('activeremovechanneloption');
	}
}

SubscriptionPopupView.prototype.getChannelName = function() {

	var channel = $('#channelText').val().trim();
	if(!channel) {
		channel = $('#selectedChannel').text().trim();
	}

    return channel;
}

SubscriptionPopupView.prototype.getCheckedChannelSlugs = function () {

    var checkedChannelSlugs = $('#browser').find('input:checked');
    if (checkedChannelSlugs.size() > 0) {

        var channelSlugs = [];

        checkedChannelSlugs.each(function () {
            channelSlugs.push($(this).attr('slug'));
        });

        return channelSlugs;
    }

    return [null];
}

SubscriptionPopupView.prototype.getOpenChannelSlugs = function () {

    var checkedChannelSlugs = $('#browser').find('.collapsable');

    if (checkedChannelSlugs.size() > 0) {

        var channelSlugs = [];

        checkedChannelSlugs.each(function () {

            if ($(this).attr('slug')) {
                channelSlugs.push($(this).attr('slug'));
            }
        });

        return channelSlugs;
    }

    return [null];
}

SubscriptionPopupView.prototype.getCheckedChannelModels = function () {

    var channelModels = [];

    var channelSlugs = this.getCheckedChannelSlugs();
    for (var i = 0; i < channelSlugs.length; i++) {
        var channelModel = pageModel.getChannelModel(channelSlugs[i]);
        channelModels.push(channelModel);
    }

    return channelModels;
}

SubscriptionPopupView.prototype.getOpenChannelModels = function () {

    var channelModels = [];

    var channelSlugs = this.getOpenChannelSlugs();
    for (var i = 0; i < channelSlugs.length; i++) {
        var channelModel = pageModel.getChannelModel(channelSlugs[i]);
        channelModels.push(channelModel);
    }

    return channelModels;
}

SubscriptionPopupView.prototype.getSelectedChannelSlug = function() {
	return $('.selectedChannel').attr('slug');
}

SubscriptionPopupView.prototype.getSelectedChannelName = function() {
	return $('.selectedChannel').text();
}

SubscriptionPopupView.prototype.getCheckedShows = function() {

	var showSlugs = []
	$(".channelItem." + SHOW + ":checked").each(function(){
		showSlugs.push($(this).val());
	});

	return showSlugs;
}

SubscriptionPopupView.prototype.getCheckedEpisodes = function() {

	var episodeSlugs = []
	$(".channelItem." + EPISODE + ":checked").each(function(){
		episodeSlugs.push($(this).val());
	});

	return episodeSlugs;
}

SubscriptionPopupView.prototype.getCheckedSearches = function() {

	var searchGuids = []
	$(".channelItem." + SEARCH + ":checked").each(function(){
		searchGuids.push($(this).val());
	});

	return searchGuids;
}

SubscriptionPopupView.prototype.changeChannelsPopup = function(_channelModel, _subscriptionBindingModel) {

	var obj = {
	    Slug: _channelModel.Slug,
        Header : "Set Channels for Selected Items",
		Type : CHANNEL
	};
	
    popupController.open("changeChannelTemplate", obj);
    
    this.populateSubscriptionList(_subscriptionBindingModel);
    
    this.populateChannelTreeview();
    this.bindChannelListeners();
}

SubscriptionPopupView.prototype.changeChannelPopup = function (_type, _slug) {

    var channelModels = [];

    if (_type == SHOW) {

        var show = pageModel.getShow(_slug);
        var obj = {
            Type: SHOW,
            Slug: show.Slug,
            Header: "Set Channels for Selected Show"
        };

        channelModels = show.Channels;

    } else if (_type == EPISODE) {

        var episode = pageModel.getEpisode(_slug);
        var obj = {
            Type: EPISODE,
            Slug: episode.Slug,
            Header: "Set Channels for Selected Episode"
        };

        channelModels = episode.Channels;
    }

    popupController.open("changeChannelTemplate", obj);

    this.populateChannelTreeview(channelModels);
    this.bindChannelListeners();
}

SubscriptionPopupView.prototype.changeFeedImporterChannelPopup = function (_feedSlug, _channelModels) {

    var obj = {
        Slug: _feedSlug,
        Type: SHOW
    };

    popupController.open("feedImporterChangeChannelTemplate", obj);

    this.populateChannelTreeview(_channelModels);
    this.bindChannelListeners();
}

SubscriptionPopupView.prototype.changeFeedImporterChangeAllChannelsPopup = function () {

    var obj = {
        Slug: "",
        Type: SHOW
    };

    popupController.open("feedImporterChangeAllChannelsTemplate", obj);

    this.populateChannelTreeview();
    this.bindChannelListeners();
}

SubscriptionPopupView.prototype.createSearchSubscriptionPopup = function(_type, _query) {

    var obj = {
        "query" : _query,
        "type" : _type
    };
    
    popupController.open("searchSubscriptionTemplate", obj);
    
    this.populateChannelTreeview();

    this.bindChannelListeners();
}

SubscriptionPopupView.prototype.removeChannelPopup = function (_channelModel, _subscriptionBindingModels) {

    if (_subscriptionBindingModels.length > 0) {

        popupController.open("removeChannelItemsTemplate", _channelModel);

        this.populateSubscriptionList(_subscriptionBindingModels);

        if (!isSpecialChannel(_channelModel.Slug)) {
            var html = "<div style='font-weight: bold; margin-top: 15px;' class='small'>or <a href='javascript:subscriptionController.submitRemoveChannel(\"" + _channelModel.Slug + "\");' style='margin-left: 8px;'>Remove channel and all items in it.</a></div>";
            $("#removeEntireChannelContainer").append(html);
        }

    } else {

        popupController.open("removeChannelTemplate", _channelModel);
    }
}

SubscriptionPopupView.prototype.updateChannelPrefs = function(_channelModel, _subscriptionBindingModels) {

    popupController.open("channelPrefsTemplate", _channelModel);
    
    this.setMediaTypeControl(this.globalSubscriptionModel.RolledUpMediaTypes)
    this.setMaxEpisodesControl(this.globalSubscriptionModel.RolledUpMaxEpisodes);
    this.setMaxDaysControl(this.globalSubscriptionModel.RolledUpMaxDays, this.globalSubscriptionModel.RolledUpDaysType);
    this.setMinExperienceControl(this.globalSubscriptionModel.RolledUpMinExperience);

	this.populateSubscriptionList(_subscriptionBindingModels);

    this.bindShowListeners();
}

SubscriptionPopupView.prototype.renameChannelPopup = function(_channelModel) {

    popupController.open("renameChannelTemplate", _channelModel);
}


/***************************************************************
 * Episode Subscriptions Popup
 ***************************************************************/ 

SubscriptionPopupView.prototype.updateEpisodeSubscriptionPopup = function(_episode) {

    popupController.open("episodePrefsTemplate", _episode);
    this.updateEpisodePopup(_episode.SubscriptionModel);
}

SubscriptionPopupView.prototype.updateEpisodePopup = function(_subscription) {
    
    var episodePrefs = _subscription.EpisodePrefs;
    var showPrefs = _subscription.ShowPrefs;

    // episode prefs
    if(episodePrefs != null) {

        $('#episodeOptions').find('.prefs').show();

        if(episodePrefs.KeepDays != null && episodePrefs.KeepDays < INT_MAX) {
            $('input.keepEpisodeDaysRadio.limit').attr('checked', true);
            $('input#keepEpisodeDaysText').enable().val(episodePrefs.KeepDays);
        } else {
            $('input.keepEpisodeDaysRadio.noLimit').attr('checked', true);
            $('input#keepEpisodeDaysText').disable();
        }

        if(episodePrefs.MinExperience != null && episodePrefs.MinExperience > 0) {
        
            $('input.minEpisodeExperienceRadio.limit').attr('checked', true);
            $('input#minEpisodeExperienceText').enable().val(episodePrefs.MinExperience);
        } else {
        
            $('input.minEpisodeExperienceRadio.noLimit').attr('checked', true);
            $('input#minEpisodeExperienceText').disable();
        }
        

    // show prefs
    } else if(showPrefs != null) {
    
        $('input.keepEpisodeDaysRadio.noLimit').attr('checked', true);
        $('input#keepEpisodeDaysText').disable();

        $('input.minEpisodeExperienceRadio.limit').attr('checked', true);
        $('input#minEpisodeExperienceText').enable().val(showPrefs.RolledUpMinExperience);

        $('#episodeOptions').find('.rolledUpPrefs').show();
    }
    
    var keepDaysString = this.generateKeepDaysString(showPrefs);
    var minExperienceString = this.generateMinEpisodeExperienceString(showPrefs);

    $('#episodeOptions').find('.rolledUpPrefs').append("<div style='float: left;'>" + keepDaysString + minExperienceString + "</div><div style='clear: left;'></div>");
    
    this.bindEpisodeListeners();
}

SubscriptionPopupView.prototype.bindEpisodeListeners = function() {

    $('input.keepEpisodeDaysRadio').bind('click', function(_event) {

        if($(this).hasClass('limit')) {
            $('#keepEpisodeDaysText').enable();
        } else {
            $('#keepEpisodeDaysText').disable();
        }
    });

    $('input.minEpisodeExperienceRadio').bind('click', function(_event) {

        if($(this).hasClass('limit')) {
            $('#minEpisodeExperienceText').enable();
        } else {
            $('#minEpisodeExperienceText').disable();
        }
    });
}

/***************************************************************
 * Episode Preference Strings
 ***************************************************************/ 

SubscriptionPopupView.prototype.generateMinEpisodeExperienceString = function(_subscription) {
    
    var experienceHtml = "Remove this episode after listening to " + _subscription.RolledUpMinExperience + "%.";
    return "<div>" + experienceHtml + "</div>";
}

SubscriptionPopupView.prototype.generateKeepDaysString = function(_showPrefs) {

    var maxDaysHtml = "";
    if(_showPrefs.RolledUpMaxDays > 0) {
    
        maxDaysHtml = "This episode will expire " + _showPrefs.RolledUpMaxDays + " ";
        switch(_showPrefs.RolledUpDaysType)
        {
        case DAYS_TYPE_ALLDAYS:
            maxDaysHtml += "day";
            break;
            
        case DAYS_TYPE_WEEKDAYS:
            maxDaysHtml += "week day";
            break;
            
        case DAYS_TYPE_SMARTDAYS:
            maxDaysHtml += "smart day";
            break;                    
        }
        maxDaysHtml += pluralize(_showPrefs.RolledUpMaxDays);
        maxDaysHtml += " after it was published.";

    } else {
        
        maxDaysHtml = "Do not let episodes expire by date.";
    }

    return "<div>" + maxDaysHtml + "</div>";
}


/***************************************************************
 * Episode Getters
 ***************************************************************/ 

SubscriptionPopupView.prototype.getKeepEpisodeDaysText = function() {

    return $('input#keepEpisodeDaysText').attr('value').trim();
}

SubscriptionPopupView.prototype.getKeepEpisodeDays = function() {
    
    if($('#episodeOptions').find('.prefs').css('display') == 'none') {
        return null;
    }

    if($('.keepEpisodeDaysRadio:checked').hasClass('limit')) {    
        return parseInt(this.getKeepEpisodeDaysText());
    } else {
        return 0;
    }
}

SubscriptionPopupView.prototype.getMinEpisodeExperience = function() {

    if($('#episodeOptions').find('.prefs').css('display') == 'none') {
        return null;
    }

    if($('.minEpisodeExperienceRadio:checked').hasClass('limit')) {    
        var minExperience = $("#minEpisodeExperienceText").val().trim();
        return parseInt(minExperience);
    } else {
        return 0;
    }
    
}

SubscriptionPopupView.prototype.isValidEpisode = function() {

    var minExperience = this.getMinEpisodeExperience();
    var keepDays = this.getKeepEpisodeDaysText();
    
    var regExp = new RegExp("^[0-9]+$");    
    
    if(keepDays != null && $('input.keepEpisodeDaysRadio:checked').hasClass('limit')) {
        if(!regExp.test(keepDays)) {
            alert("Please enter a valid number of days");
            return false;
        }
        
        if(minExperience < 0) {
            alert("Please enter a valid number of days");
            return false;
        }
    }

    if(minExperience != null && $('input.minEpisodeExperienceRadio:checked').hasClass('limit')) {
        if(minExperience == "" || !regExp.test(minExperience)) {
            alert("Please enter a valid number between 1 and 100 for experience");
            return false;
        }
        minExperience = parseInt(minExperience);
        if(minExperience < 1 || minExperience > 100) {
            alert("Please enter a valid number between 1 and 100 for experience");
            return false;
        }
    }

    return true;
}

/***************************************************************
 * Is First Subscription Popup
 ***************************************************************/ 

SubscriptionPopupView.prototype.popupFirstSubscription = function() {

    popupController.open("firstSubscriptionTemplate");
}

/* BEGIN: common/subscription_controller */

var CHANNEL = "Channel",
	SHOW = "Show",
    EPISODE = "Episode",
    SEARCH = "Search";

var ITUNES = 0,
    ZUNE = 2,
	WINAMP = 3,
	RSS = 4
    
if($.browser.msie && $.browser.version == 6) {
    var EPISODECOUNT_CIRCLE        = "/images/rollover/episodecount_circle.gif",
        EPISODECOUNT_CIRCLE_EMPTY  = "/images/rollover/episodecount_circle_empty.gif";
} else {
    var EPISODECOUNT_CIRCLE        = "/images/rollover/episodecount_circle.png",
        EPISODECOUNT_CIRCLE_EMPTY  = "/images/rollover/episodecount_circle_empty.png";
}

function SubscriptionController()
{
    this.subscriptionPopupView = new SubscriptionPopupView();
}

SubscriptionController.prototype.init = function(_globalSubscriptionModel) {

    this.subscriptionPopupView.init(_globalSubscriptionModel);
}

SubscriptionController.prototype.getShowSubscriptionText = function(_show) {

	var subscriptionString = "";
	
	subscriptionString += "<div>" + this.subscriptionPopupView.generateMediaTypeString(_show.SubscriptionModel) + "</div>";
	subscriptionString += "<div>" + this.subscriptionPopupView.generateMaxEpisodesString(_show.SubscriptionModel) + "</div>";
	subscriptionString += "<div>" + this.subscriptionPopupView.generateMaxDaysString(_show.SubscriptionModel) + "</div>";
	subscriptionString += "<div>" + this.subscriptionPopupView.generateMinExperienceString(_show.SubscriptionModel) + "</div>";
	
	return subscriptionString;
}

SubscriptionController.prototype.updateSubscription = function(_episode) {

    if(_episode.Show.IsShowSubscription) {
    
        $('.' + _episode.Show.Slug + '_Show_subscriptionIcon').css('background-image', "url(" + TRASH_ICON + ")");
        $('.' + _episode.Show.Slug + '_Show_subscriptionText').html("Remove");
    
        $('.' + _episode.Show.Slug + '_Show_prefs').show();
    } else {

        $('.' + _episode.Show.Slug + '_Show_subscriptionIcon').css('background-image', "url(" + ADD_ICON + ")");
        $('.' + _episode.Show.Slug + '_Show_subscriptionText').html("Add it");

        $('.' + _episode.Show.Slug + '_Show_prefs').hide();
    }
    
    if(_episode.InPlaylist) {

        $('.' + _episode.Slug + '_Episode_subscriptionIcon').css('background-image', "url(" + TRASH_ICON + ")");
        $('.' + _episode.Slug + '_Episode_subscriptionText').html("Remove");

        $('.' + _episode.Slug + '_Episode_prefs').show();
    } else {

        $('.' + _episode.Slug + '_Episode_subscriptionIcon').css('background-image', "url(" + ADD_ICON + ")");
        $('.' + _episode.Slug + '_Episode_subscriptionText').html("Add it");

        $('.' + _episode.Slug + '_Episode_prefs').hide();
    }
}

SubscriptionController.prototype.updateEpisodeCount = function (_show) {

    if (_show.IsInferred) {

        $('.' + _show.Slug + "_EpisodeCountString").html("<img src='" + PLAYLIST_INFERRED + "' />");
        $('.' + _show.Slug + "_EpisodeCountImage").fadeIn(300, null);

    } else if (_show.EpisodeCount != null) {

        if (_show.EpisodeCount > 0) {
            $('.' + _show.Slug + "_EpisodeCountString").css('color', '#777777');
            $('.' + _show.Slug + "_EpisodeCountImage").css('background-image', "url(" + EPISODECOUNT_CIRCLE + ")");
        } else {
            $('.' + _show.Slug + "_EpisodeCountString").css('color', '#A0A0A0');
            $('.' + _show.Slug + "_EpisodeCountImage").css('background-image', "url(" + EPISODECOUNT_CIRCLE_EMPTY + ")");
        }

        $('.' + _show.Slug + "_EpisodeCountString").html(_show.EpisodeCount);
        $('.' + _show.Slug + "_EpisodeCountImage").fadeIn(300, null);

    } else {

        $(".subscriptiontypes[show=" + _show.Slug + "]").hide();
        $('.' + _show.Slug + "_EpisodeCountString").html("");
        $('.' + _show.Slug + "_EpisodeCountImage").hide();
    }
}


/***************************************************************
 * Toggle Show Subscription
 ***************************************************************/

SubscriptionController.prototype.toggleShowSubscription = function (_slug) {

    var show = pageModel.getShow(_slug);
    if (show.IsShowSubscription) {

        if (typeof collectionController == "undefined" || isSpecialChannel(collectionController.CurrentChannel.Slug)) {

            var options = {
                header: "Are you sure you would like to remove this show?",
                buttons: [
                    { value: "Remove from all channels", callback: function () { subscriptionController.submitRemoveShowSubscription(_slug); } },
                    { value: "Cancel", callback: function () { popupController.hidePopup(); } }
                ]
            }

        } else {

            var options = {
                header: "Are you sure you would like to remove this show?",
                buttons: [
                    { value: "Remove from all channels", callback: function () { subscriptionController.submitRemoveShowSubscription(_slug); } },
                    { value: "Remove from this channel", callback: function () { subscriptionController.submitRemoveShowSubscription(_slug, collectionController.CurrentChannel.Slug); } },
                    { value: "Cancel", callback: function () { popupController.hidePopup(); } }
                ]
            }
        }

        $.popup(options);

    } else {

        var params = {
            doRefresh: false,
            onSuccess: function (_result) { subscriptionController.showSubscriptionAndCheckForFirstSubscriptionCallback(_result, new Array(_slug)); },
            onFailure: function (error) { alert("Error subscriping to show."); },
            method: '/WebServices/SubscriptionService_v2_0.asmx/SubscribeToShow',
            args: { showSlug: _slug }
        };

        webService.invoke(params);
    }
}

SubscriptionController.prototype.submitRemoveShowSubscription = function (_slug, _channelSlug) {

    if(!_channelSlug)
        _channelSlug = null;

    var params = {
        onSuccess: function (_result) { subscriptionController.showSubscriptionCallback(_result, new Array(_slug)); },
        onFailure: function (_error) { alert("Error Unsubscribing."); },
        method: '/WebServices/SubscriptionService_v2_0.asmx/Unsubscribe',
        args: { showSlugs: new Array(_slug),
                episodeSlugs: [],
                searchGuids: [],
                channelSlug: _channelSlug
        }
    };

    webService.invoke(params);
}

SubscriptionController.prototype.checkFirstSubscription = function(_result) {

    if (_result.IsFirstSubscription) {
        this.subscriptionPopupView.popupFirstSubscription();
    }
}

SubscriptionController.prototype.showSubscriptionAndCheckForFirstSubscriptionCallback = function(_result, _slugs) {

    if(_result) {

        this.showSubscriptionCallback(_result.Episodes, _slugs);
        this.checkFirstSubscription(_result);
    }
}

SubscriptionController.prototype.showSubscriptionFeedImporterCallback = function (_showSlugs) {

    var channelModels = this.subscriptionPopupView.getCheckedChannelModels();

    for (var i = 0; i < _showSlugs.length; i++) {

        for (var j = 0; j < FeedImporterController.saveData.length; j++) {

            if (FeedImporterController.saveData[j].FeedInfo.Slug == _showSlugs[i]) {
                this.mergeChannels(FeedImporterController.saveData[j].FeedInfo.Channels, channelModels);
            }
        }
    }
}

SubscriptionController.prototype.mergeChannels = function (_originalChannelModels, _newChannelModels) {

    for (var i = 0; i < _newChannelModels.length; i++) {

        var addIt = true;
        for (var j = 0; j < _originalChannelModels.length; j++) {

            if (_newChannelModels[i].Slug == _originalChannelModels[j].Slug) {
                addIt = false;
                break;
            }
        }

        if (addIt)
            _originalChannelModels.push(_newChannelModels[i]);
    }
}

SubscriptionController.prototype.showSubscriptionCallback = function (_result, _slugs, _channelSlugs) {

    var episodes = _result;

    if (episodes == null)
        return;

    if (typeof episodes.length != "undefined") {

        if (episodes.length == 0) {

            episodes = [];
            for (var i = 0; i < _slugs.length; i++) {
                episodes = episodes.concat(pageModel.getEpisodesForShow(_slugs[i]));
            }

            for (var i = 0; i < episodes.length; i++) {
                episodes[i].Show.IsShowSubscription = true;
                episodes[i].Show.EpisodeCount = 0;
                episodes[i].Show.IsInferred = true;
                episodes[i].InPlaylist = false;

                if (pageModel.playlistContainsEpisode(episodes[i].Slug)) {
                    pageModel.removePlaylistEpisode(episodes[i]);

                    if (collectionWidget) {
                        collectionWidget.removeEpisode(episodes[i]);
                    }
                }

                if (_channelSlugs) {

                    episodes[i].Show.Channels = [];
                    for (var c = 0; c < _channelSlugs.length; c++) {
                        var channelModel = pageModel.getChannelModel(_channelSlugs[c]);
                        episodes[i].Show.Channels.push(channelModel);
                    }
                }
            }

        } else {

            var originalEpisodeSlugs = [];
            for (var i = 0; i < _slugs.length; i++) {
                originalEpisodeSlugs = originalEpisodeSlugs.concat(pageModel.getEpisodeSlugsForShow(_slugs[i]));
            }

            pageModel.updateEpisodes(episodes);

            if (collectionWidget) {

                for (var i = 0; i < _slugs.length; i++) {
                    if (!pageModel.playlistContainsShow(_slugs[i])) {
                        for (var j = 0; j < episodes.length; j++) {
                            if (episodes[j].Show.Slug == _slugs[i]) {
                                collectionWidget.addShow(episodes[j]);
                                break;
                            }
                        }
                    }
                }
            }

            var newPlaylistEpisodes = [];
            for (var i = 0; i < episodes.length; i++) {
                if (!pageModel.playlistContainsEpisode(episodes[i])) {
                    pageModel.addPlaylistEpisode(episodes[i]);

                    newPlaylistEpisodes.push(episodes[i]);
                }
            }

            if (collectionWidget) {
                collectionWidget.addEpisodes(newPlaylistEpisodes);
            }


            for (var i = 0; i < episodes.length; i++) {
                for (var j = 0; j < originalEpisodeSlugs.length; j++) {
                    if (episodes[i].Slug == originalEpisodeSlugs[j]) {
                        originalEpisodeSlugs.splice(j--, 1);
                    }
                }
            }

            var showIsSubscribed = episodes[0].Show.IsShowSubscription;
            var showEpisodeCount = episodes[0].Show.EpisodeCount;
            for (var j = 0; j < originalEpisodeSlugs.length; j++) {

                var episode = pageModel.getEpisode(originalEpisodeSlugs[j]);
                episode.Show.IsShowSubscription = showIsSubscribed;
                episode.Show.EpisodeCount = showEpisodeCount;
                episode.Show.IsInferred = true;
                episode.InPlaylist = false;

                episodes.push(episode);

                if (pageModel.playlistContainsEpisode(episode)) {
                    pageModel.removePlaylistEpisode(episode);

                    if (collectionWidget) {
                        collectionWidget.removeEpisode(episode);
                    }
                }
            }
        }

    } else {

        episodes = [];
        for (var i = 0; i < _slugs.length; i++) {
            episodes = episodes.concat(pageModel.getEpisodesForShow(_slugs[i]));
        }

        if (episodes.length > 0) {

            if (collectionWidget && pageModel.playlistContainsShow(episodes[0].Show.Slug)) {
                collectionWidget.removeShow(episodes[0]);
            }

            for (var i = 0; i < episodes.length; i++) {
                episodes[i].Show.IsShowSubscription = false;
                episodes[i].Show.EpisodeCount = null;
                episodes[i].Show.IsInferred = false;
                episodes[i].InPlaylist = false;

                episodes[i].Channels = [];

                if (pageModel.playlistContainsEpisode(episodes[i].Slug)) {
                    pageModel.removePlaylistEpisode(episodes[i]);

                    if (collectionWidget) {
                        collectionWidget.removeEpisode(episodes[i]);
                    }
                }
            }
        }
    }

    for (var i = 0; i < episodes.length; i++) {

        this.updateSubscription(episodes[i]);

        ratingController.updateRatings(episodes[i]);
        favoriteController.updateFavorite(episodes[i]);

        this.updateEpisodeCount(episodes[i].Show);
        ratingController.updateRatings(episodes[i].Show);
        favoriteController.updateFavorite(episodes[i].Show);
        rolloverController.updateHud(episodes[i].Show);
    }

    rolloverController.bindListeners();

    popupController.hidePopup();

    headerController.updateHeader();
}

SubscriptionController.prototype.getEpisodeChannels = function(_episodes) {

    var channels = [];
    for(var e=0; e < _episodes.length; e++) {
    
        if(_episodes[e].Channels) {
            for(var c=0; c < _episodes[e].Channels.length; c++) {
            
                var addIt=true;
                for(var i=0; i < channels.length; i++) {
                    if(_episodes[e].Channels[c].Slug == channels[i].Slug) {
                        addIt = false;
                        break;
                    }
                }
                
                if(addIt) {
                    channels.push(_episodes[e].Channels[c]);
                }
            }
        }
    }
    
    return channels;
}


/***************************************************************
 * Toggle Episode Subscription
 ***************************************************************/ 

SubscriptionController.prototype.toggleEpisodeSubscription = function(_slug) {

    var episode = pageModel.getEpisode(_slug);

    if (episode.InPlaylist) {

        if (typeof collectionController == "undefined") {

            var options = {
                header: "Are you sure you would like to remove this episode?",
                buttons: [
                    { value: "Remove from all channels", callback: function () { subscriptionController.submitRemoveEpisodeSubscription(_slug); } },
                    { value: "Cancel", callback: function () { popupController.hidePopup(); } }
                ]
            }

        } else {

            var options = {
                header: "Are you sure you would like to remove this episode?",
                buttons: [
                    { value: "Remove from all channels", callback: function () { subscriptionController.submitRemoveEpisodeSubscription(_slug); } },
                    { value: "Remove from this channel", callback: function () { subscriptionController.submitRemoveEpisodeSubscription(_slug, collectionController.CurrentChannel.Slug); } },
                    { value: "Cancel", callback: function () { popupController.hidePopup(); } }
                ]
            }
        }

        $.popup(options);
                    
    } else {

        var params = {
            doRefresh : false,
            onSuccess : function(_result) { subscriptionController.showSubscriptionCallback(_result, new Array(episode.Show.Slug)); },
            onFailure : function(_error) { alert("Error subscribing to episode."); },
            method : '/WebServices/SubscriptionService_v2_0.asmx/SubscribeToEpisode',
            args : { episodeSlug: _slug
            }
        };

        webService.invoke(params);
    }
}

SubscriptionController.prototype.submitRemoveEpisodeSubscription = function (_episodeSlug, _channelSlug) {

    if(!_channelSlug)
        _channelSlug = null;

    var episode = pageModel.getEpisode(_episodeSlug);

    var params = {
        onSuccess: function (_result) { subscriptionController.showSubscriptionCallback(_result, new Array(episode.Show.Slug)); },
        onFailure: function (_error) { alert("Error Unsubscribing."); },
        method: '/WebServices/SubscriptionService_v2_0.asmx/Unsubscribe',
        args: { showSlugs: [],
                episodeSlugs: new Array(_episodeSlug),
                searchGuids: [],
                channelSlug: _channelSlug
        }
    };

    webService.invoke(params);
}


/***************************************************************
 * Edit Prefs
 ***************************************************************/ 

SubscriptionController.prototype.editPrefs = function(_id) {
    this.subscriptionPopupView.editPrefs(_id);
}

SubscriptionController.prototype.removePrefs = function(_id) {
    this.subscriptionPopupView.removePrefs(_id);
}


/***************************************************************
 * Prefs
 ***************************************************************/ 

SubscriptionController.prototype.popupShowPrefs = function(_slug) {

    var show = pageModel.getShow(_slug);
    this.subscriptionPopupView.updateShowSubscriptionPopup(show);
}

SubscriptionController.prototype.popupEpisodePrefs = function(_slug) {

    var episode = pageModel.getEpisode(_slug);
    this.subscriptionPopupView.updateEpisodeSubscriptionPopup(episode);
}

/***************************************************************
 * Submit Prefs
 ***************************************************************/ 

SubscriptionController.prototype.submitEpisodePrefs = function(_slug) {

    if(this.subscriptionPopupView.isValidEpisode()) {
    
        var keepDays = this.subscriptionPopupView.getKeepEpisodeDays();
        var experience = this.subscriptionPopupView.getMinEpisodeExperience();
        
        var keepForever = (keepDays == 0 && experience == 0);
        
        if(keepDays == 0) {
            keepDays = null;
        }
        
        if(experience == 0) {
            experience = null;
        }
        
        var episode = pageModel.getEpisode(_slug);
        
        var params = {
            onSuccess : function(_result) { subscriptionController.showSubscriptionCallback(_result, new Array(episode.Show.Slug)); },
            onFailure : function(_error) { alert("Error updating episode subscription preferences."); },
            method : '/WebServices/SubscriptionService_v2_0.asmx/UpdateEpisodeSubscriptionPrefs',
            args : {episodeSlug : _slug,
                    maxDays : keepDays,
                    minExperience : experience,
                    keepForever: keepForever }
        };
        
        webService.invoke(params);
    }}

SubscriptionController.prototype.submitShowPrefs = function(_slug) {

    var show = pageModel.getShow(_slug);
    if (this.subscriptionPopupView.subscriptionStateChangedForShow(show)) {

        var inactive = this.subscriptionPopupView.getInactiveCheckValue();

        var params = {
            onSuccess : function(_result) { subscriptionController.showSubscriptionCallback(_result, new Array(_slug)); },
            onFailure : function(_error) { alert("Error pausing show subscription"); },
            method : '/WebServices/SubscriptionService_v2_0.asmx/PauseShowSubscription',
            args : {showSlugs : new Array(_slug),
                    pauseSubscription : inactive }
        };
        
        webService.invoke(params);
    
    } else if(this.subscriptionPopupView.isValid()) {
    
        var mediaType = this.subscriptionPopupView.getMediaTypes();
        var maxEpisodes = this.subscriptionPopupView.getMaxEpisodes();
        var maxDays = this.subscriptionPopupView.getMaxDays();
        var daysType = this.subscriptionPopupView.getDaysType();
        var minExperience = this.subscriptionPopupView.getMinExperience();

        var params = {
            onSuccess : function(_result) { subscriptionController.showSubscriptionCallback(_result, new Array(_slug)); },
            onFailure : function(_error) { alert("Error updating show preferences."); },
            method : '/WebServices/SubscriptionService_v2_0.asmx/UpdateShowPrefs',
            args : {showSlugs : new Array(_slug),
                    mediaType : mediaType,
                    maxEpisodes : maxEpisodes,
                    maxDays : maxDays,
                    daysType : daysType,
                    minExperience : minExperience }
        };
        
        webService.invoke(params);
    }
}


/***************************************************************
 * Set Default Prefs
 ***************************************************************/ 

SubscriptionController.prototype.defaultPrefs = function(_type, _slug) {

    var showSlugs = [];
    var episodeSlugs = [];
    var allShowSlugs = [];
    
    switch(_type)
    {
    case CHANNEL:

        showSlugs = this.subscriptionPopupView.getCheckedShows();
        allShowSlugs = showSlugs;
        break;
        
    case SHOW:

        showSlugs.push(_slug);
        allShowSlugs.push(_slug);
        break;
        
    case EPISODE:

        episodeSlugs.push(_slug);
        
        var episode = pageModel.getEpisode(_slug);
        if (episode != null) {
            allShowSlugs.push(episode.Show.Slug);
        }
        break;
    }

    var params = {
        onSuccess : function(_result) { subscriptionController.showSubscriptionCallback(_result, allShowSlugs); },
        onFailure : function(_error) { alert("Error resetting preferences."); },
        method : '/WebServices/SubscriptionService_v2_0.asmx/ResetPreferences',
        args : {showSlugs : showSlugs,
                episodeSlugs : episodeSlugs }
        
    };
    
    webService.invoke(params);
    
}

/***************************************************************
 * Channel Change Prefs
 ***************************************************************/ 
 
SubscriptionController.prototype.changeChannelsPopup = function(_channelModel, _subscriptionBindingModels) {

	this.subscriptionPopupView.changeChannelsPopup(_channelModel, _subscriptionBindingModels);
}

SubscriptionController.prototype.changeChannelPopup = function(_type, _slug) {

    this.subscriptionPopupView.changeChannelPopup(_type, _slug);
}

SubscriptionController.prototype.changeFeedImporterChannelPopup = function (_feedSlug) {

    var channelModels = [];
    for (var i = 0; i < FeedImporterController.saveData.length; i++) {

        if (FeedImporterController.saveData[i].FeedInfo.Slug == _feedSlug) {
            channelModels = FeedImporterController.saveData[i].FeedInfo.Channels;
            break;
        }
    }

    this.subscriptionPopupView.changeFeedImporterChannelPopup(_feedSlug, channelModels);
}

SubscriptionController.prototype.changeFeedImporterChangeAllChannelsPopup = function () {

    this.subscriptionPopupView.changeFeedImporterChangeAllChannelsPopup();
}

SubscriptionController.prototype.createSearchSubscriptionPopup = function(_query) {
    
    this.subscriptionPopupView.createSearchSubscriptionPopup(SEARCH, _query);
}

SubscriptionController.prototype.submitChangeChannel = function (_type, _slug) {

    var showSlugs = [];
    var episodeSlugs = [];
    var searchGuids = [];

    var updateShows = [];

    var channelSlugs = subscriptionController.subscriptionPopupView.getCheckedChannelSlugs();
    var removeExistingChannels = true;

    switch (_type)
    {
        case SHOW:

            var channelSlugsForShow = channelSlugs;

            showSlugs.push(_slug);
            updateShows = showSlugs;

            break;

        case EPISODE:

            episodeSlugs.push(_slug);

            var episode = pageModel.getEpisode(_slug);
            updateShows.push(episode.Show.Slug);

            break;

        case CHANNEL:

            showSlugs = this.subscriptionPopupView.getCheckedShows();
            episodeSlugs = this.subscriptionPopupView.getCheckedEpisodes();
            searchGuids = this.subscriptionPopupView.getCheckedSearches();

            removeExistingChannels = false;

            updateShows = showSlugs;
            break;
    }

    var params = {
        onSuccess: function (_result) { subscriptionController.showSubscriptionCallback(_result, updateShows, channelSlugs); },
        onFailure: function (_error) { alert("Error changing channels."); },
        method: '/WebServices/SubscriptionService_v2_0.asmx/ChangeChannel',
        args: { showSlugs: showSlugs,
                episodeSlugs: episodeSlugs,
                searchGuids: searchGuids,
                channelSlugs: channelSlugs,
                removeExistingChannels: removeExistingChannels
        }
    };

    webService.invoke(params);

}

SubscriptionController.prototype.submitFeedImporterChangeChannel = function (_feedSlug) {

    var params = {
        onSuccess: function (_result) { subscriptionController.showSubscriptionFeedImporterCallback([_feedSlug]); },
        onFailure: function (_error) { alert("Error changing channels."); },
        method: '/WebServices/SubscriptionService_v2_0.asmx/ChangeChannel',
        args: { showSlugs: new Array(_feedSlug),
                episodeSlugs: [],
                searchGuids: [],
                channelSlugs: function () { return subscriptionController.subscriptionPopupView.getCheckedChannelSlugs(); },
                removeExistingChannels: true
        }
    };

    webService.invoke(params);

}

SubscriptionController.prototype.submitFeedImporterChangeAllChannels = function () {

    var showSlugs = [];
    for (var i = 0; i < FeedImporterController.saveData.length; i++) {
        showSlugs.push(FeedImporterController.saveData[i].FeedInfo.Slug);
    }

    var params = {
        onSuccess: function (_result) { subscriptionController.showSubscriptionFeedImporterCallback(showSlugs); },
        onFailure: function (_error) { alert("Error changing channels."); },
        method: '/WebServices/SubscriptionService_v2_0.asmx/ChangeChannel',
        args: { showSlugs: showSlugs,
                episodeSlugs: [],
                searchGuids: [],
                channelSlugs: function () { return subscriptionController.subscriptionPopupView.getCheckedChannelSlugs(); },
                removeExistingChannels: false
        }
    };

    webService.invoke(params);
}

SubscriptionController.prototype.submitSearchSubscription = function(query) {

    var params = {
        onSuccess : function(_result) { },
        onFailure : function(_error) { alert("Error creating search subscription."); },
        method : '/WebServices/SubscriptionService_v2_0.asmx/CreateSearchSubscription',
        args : { query : query,
                 channelSlugs: function () { return subscriptionController.subscriptionPopupView.getCheckedChannelSlugs(); }
        }
    };
    
    webService.invoke(params);
}

SubscriptionController.prototype.removeSearchSubscription = function(searchGuid) {

    var params = {
        onSuccess : function(_result) { },
        onFailure : function(_error) { alert("Error removing search subscription"); },
        method : '/WebServices/SubscriptionService_v2_0.asmx/RemoveSearchSubscription',
        args : {
            searchGuid : searchGuid
        }
    };
    
    webService.invoke(params);
}

SubscriptionController.prototype.removeChannelPopup = function(_channelModel, _subscriptionBindingModels) {

    this.subscriptionPopupView.removeChannelPopup(_channelModel, _subscriptionBindingModels);
}

SubscriptionController.prototype.removeSubscriptions = function () {

    var showSlugs = this.subscriptionPopupView.getCheckedShows();
    var episodeSlugs = this.subscriptionPopupView.getCheckedEpisodes();
    var searchGuids = this.subscriptionPopupView.getCheckedSearches();

    var options = {
        header: "Are you sure you would like to remove this show?",
        buttons: [
                    { value: "Remove from all channels", callback: function () { subscriptionController.submitRemoveSubscriptions(showSlugs, episodeSlugs, searchGuids); } },
                    { value: "Remove from this channel", callback: function () { subscriptionController.submitRemoveSubscriptions(showSlugs, episodeSlugs, searchGuids, collectionController.CurrentChannel.Slug); } },
                    { value: "Cancel", callback: function () { popupController.hidePopup(); } }
                ]
    }

    $.popup(options);
}

SubscriptionController.prototype.submitRemoveSubscriptions = function (_showSlugs, _episodeSlugs, _searchGuids, _channelSlug) {

    if(!_channelSlug)
        _channelSlug = null;

    var params = {
        onSuccess: function (_result) { window.location.reload(); },
        onFailure: function (_error) { alert("Error Unsubscribing."); },
        method: '/WebServices/SubscriptionService_v2_0.asmx/Unsubscribe',
        args: { showSlugs: _showSlugs,
                episodeSlugs: _episodeSlugs,
                searchGuids: _searchGuids,
                channelSlug: _channelSlug
        }
    };

    webService.invoke(params);
}

SubscriptionController.prototype.submitRemoveChannel = function (_channelSlug) {

    if (confirm("Are you sure you would like to remove this channel and all items in it?")) {

        var channelModel = pageModel.getChannelModel(_channelSlug);

        var params = {
            onSuccess: function (_result) { window.location = "/MyShows"; },
            onFailure: function (_error) { alert("Error removing channels."); },
            method: '/WebServices/SubscriptionService_v2_0.asmx/RemoveChannel',
            args: { channelSlug: channelModel.Slug,
                    deleteSubscriptions: true
            }
        };

        webService.invoke(params);
    }
}

SubscriptionController.prototype.channelPrefsPopup = function(_channelModel, _subscriptionBindingModels) {

    this.subscriptionPopupView.updateChannelPrefs(_channelModel, _subscriptionBindingModels);
}

SubscriptionController.prototype.submitCheckedShowPrefs = function () {

    if(this.subscriptionPopupView.isValid()) {
    
        var mediaType = this.subscriptionPopupView.getMediaTypes();
        var maxEpisodes = this.subscriptionPopupView.getMaxEpisodes();
        var maxDays = this.subscriptionPopupView.getMaxDays();
        var daysType = this.subscriptionPopupView.getDaysType();
        var minExperience = this.subscriptionPopupView.getMinExperience();
        
		var showSlugs = this.subscriptionPopupView.getCheckedShows();

        var params = {
            onSuccess : function(_result) { subscriptionController.showSubscriptionCallback(_result, showSlugs); },
            onFailure : function(_error) { alert("Error updating show preferences."); },
            method : '/WebServices/SubscriptionService_v2_0.asmx/UpdateShowPrefs',
            args: { showSlugs: showSlugs,
                    mediaType : mediaType,
                    maxEpisodes : maxEpisodes,
                    maxDays : maxDays,
                    daysType : daysType,
                    minExperience : minExperience }
        };
        
        webService.invoke(params);
    }    
}

SubscriptionController.prototype.renameChannelPopup = function(_channelModel) {

    this.subscriptionPopupView.renameChannelPopup(_channelModel);
}

SubscriptionController.prototype.submitRenameChannel = function(_channelSlug) {
    
    var newChannelName = this.subscriptionPopupView.getChannelName();
    
    var params = {
        onSuccess : function(_result) { window.location = "/MyShows/" + _result.Path },
        onFailure : function(_error) { alert("Error renaming channel."); },
        method : '/WebServices/SubscriptionService_v2_0.asmx/RenameChannel',
        args : {channelSlug : _channelSlug,
                newChannelName  : newChannelName }
    };
    
    webService.invoke(params);
}

SubscriptionController.prototype.iTunesLink = function (_slug) {

    var show = pageModel.getShow(_slug);
    if (pageController.isUser()) {

        if (!show.IsShowSubscription)
            this.toggleShowSubscription(_slug);

        this.generateLink(show, ITUNES);

    } else {

        this.subscriptionPopupView.requiresLoginPopup(show, ITUNES);
    }
}


SubscriptionController.prototype.WinampLink = function (_slug) {

    var show = pageModel.getShow(_slug);
    if (!show.IsShowSubscription)
        this.toggleShowSubscription(_slug);

    this.generateLink(show, WINAMP);
}

SubscriptionController.prototype.ZuneLink = function(_slug) {

	var show = pageModel.getShow(_slug);
    if (pageController.isUser()) {
    
		if (!show.IsShowSubscription)
		    this.toggleShowSubscription(_slug);

		this.generateLink(show, ZUNE);
		
    } else {
    
		this.subscriptionPopupView.requiresLoginPopup(show, ZUNE);
    }
}

SubscriptionController.prototype.generateLink = function (_show, _device) {

	var link = "";
	if (_device == ZUNE) {
	    link = _show.SubscriptionModel.PrivateRss;
        link = "zune://subscribe/?" + _show.Title + " (via Mediafly)=" + link;
	} else if(_device == ITUNES) {
        link = _show.SubscriptionModel.PrivateRss;
        link = link.replace("http", "itpc");
    } else if (_device == WINAMP) {
        link = _show.RssLink.replace("http", "pcast");
        link = "winamp://Podcast/Subscribe?url=" + link;
    }    
	window.location = link;
}


/***************************************************************
 * Context Menu Functions
 ***************************************************************/

SubscriptionController.prototype.contextMenuCreateChannel = function (_menuItem, _menu) {

    var channelModels = subscriptionController.subscriptionPopupView.getCheckedChannelModels();
    var openChannelModels = subscriptionController.subscriptionPopupView.getOpenChannelModels();

    subscriptionController.subscriptionPopupView.contextMenuCreateChannel(channelModels, openChannelModels);
}

SubscriptionController.prototype.contextMenuRemoveChannel = function (_menuItem, _menu) {

    if (!$("#removechannel").hasClass('activeremovechanneloption'))
        return;

    if (confirm("Are you sure you would like to remove this channel and all items in it?")) {

        var channelSlug = subscriptionController.subscriptionPopupView.getSelectedChannelSlug();
        var channelModel = pageModel.getChannelModel(channelSlug);

        var params = {
            hidePopup: false,
            onSuccess: function (_result) { subscriptionController.submitContextMenuRemoveChannelHandler(channelModel) },
            onFailure: function (_error) { alert("Error removing channels."); },
            method: '/WebServices/SubscriptionService_v2_0.asmx/RemoveChannel',
            args: { channelSlug: channelModel.Slug,
                    deleteSubscriptions: true
            }
        };

        webService.invoke(params);
    }
}

SubscriptionController.prototype.submitContextMenuRemoveChannelHandler = function (_channelModel) {

    var channelModels = subscriptionController.subscriptionPopupView.getCheckedChannelModels();
    var openChannelModels = subscriptionController.subscriptionPopupView.getOpenChannelModels();

    pageModel.removeChannelModel(_channelModel.Slug);

    headerController.updateMyChannels();

    this.subscriptionPopupView.populateChannelTreeview(channelModels, openChannelModels);
    this.subscriptionPopupView.bindChannelListeners();
}

SubscriptionController.prototype.contextMenuRenameChannel = function(_menuItem, _menu) {

	if (!$("#renamechannel").hasClass('activerenamechanneloption'))
		return;

	subscriptionController.subscriptionPopupView.contextMenuRenameChannel();
}

SubscriptionController.prototype.submitContextMenuRenameChannel = function () {

    var channelModels = subscriptionController.subscriptionPopupView.getCheckedChannelModels();

    var channelSlug = subscriptionController.subscriptionPopupView.getSelectedChannelSlug();
    var newChannelName = subscriptionController.subscriptionPopupView.getSelectedChannelName();
    if (channelSlug == "__newchannel__") {

        var channelModel = pageModel.getChannelModel(channelSlug);

        var params = {
            hidePopup: false,
            onSuccess: function (_result) { subscriptionController.submitContextMenuCreateChannelHandler(_result, channelModels); },
            onFailure: function (_error) { subscriptionController.errorCreatingNewChannel(); },
            method: '/WebServices/SubscriptionService_v2_0.asmx/CreateNewChannel',
            args: { channelName: newChannelName,
                    parentChannelSlug: channelModel.ParentChannelSlug
            }
        };

    } else {

        var params = {
            hidePopup: false,
            onSuccess: function (_result) { subscriptionController.submitContextMenuRenameChannelHandler(_result, channelModels) },
            onFailure: function (_error) { alert("Error renaming channel"); },
            method: '/WebServices/SubscriptionService_v2_0.asmx/RenameChannel',
            args: { channelSlug: channelSlug,
                    newChannelName: newChannelName
            }
        };
    }

    webService.invoke(params);
}

SubscriptionController.prototype.errorCreatingNewChannel = function () {

    pageModel.removeChannelModel("__newchannel__");

    var channelModels = subscriptionController.subscriptionPopupView.getCheckedChannelModels();
    var openChannelModels = subscriptionController.subscriptionPopupView.getOpenChannelModels();

    this.subscriptionPopupView.populateChannelTreeview(channelModels, openChannelModels);
    this.subscriptionPopupView.bindChannelListeners();

    alert("Error creating new channel");
}

SubscriptionController.prototype.submitContextMenuCreateChannelHandler = function (_channelModel) {

    if (_channelModel == null) {
        this.errorCreatingNewChannel();
    }

    var channelModels = subscriptionController.subscriptionPopupView.getCheckedChannelModels();
    var openChannelModels = subscriptionController.subscriptionPopupView.getOpenChannelModels();

    pageModel.replaceChannelModel("__newchannel__", _channelModel);

    headerController.updateMyChannels();

    this.subscriptionPopupView.populateChannelTreeview(channelModels, openChannelModels);
    this.subscriptionPopupView.bindChannelListeners();
}

SubscriptionController.prototype.submitContextMenuRenameChannelHandler = function (_channelModel) {

    var channelModels = subscriptionController.subscriptionPopupView.getCheckedChannelModels();
    var openChannelModels = subscriptionController.subscriptionPopupView.getOpenChannelModels();

    pageModel.replaceChannelModel(_channelModel.Slug, _channelModel);

    headerController.updateMyChannels();

    this.subscriptionPopupView.populateChannelTreeview(channelModels, openChannelModels);
    this.subscriptionPopupView.bindChannelListeners();
}

/* BEGIN: common/rollover_controller */

var PADDING = 10;

function RolloverController()
{
    try {
        this.showRolloverTemplate = TrimPath.parseDOMTemplate((!$.browser.msie || $.browser.version != 6) ? "showRolloverTemplate" : "showRolloverIE6Template");
    } catch(e) { }

    try {
        this.searchResultRolloverTemplate = TrimPath.parseDOMTemplate((!$.browser.msie || $.browser.version != 6) ? "searchResultRolloverTemplate" : "searchResultRolloverIE6Template");
        this.searchResultEpisodeRolloverTemplate = TrimPath.parseDOMTemplate("searchResultEpisodeRolloverTemplate");
    } catch(e) { }
    
    this.subscriptionPreviewTemplate = TrimPath.parseDOMTemplate("subscriptionPreviewTemplate");
}

RolloverController.prototype.init = function() {

    this.bindListeners();
}

RolloverController.prototype.initTemplate = function() {

    if(!this.showRolloverTemplate) {
        this.showRolloverTemplate = TrimPath.parseDOMTemplate("showRolloverTemplate");
    }

    try {
        this.searchResultRolloverTemplate = TrimPath.parseDOMTemplate("searchResultRolloverTemplate");
        this.searchResultEpisodeRolloverTemplate = TrimPath.parseDOMTemplate("searchResultEpisodeRolloverTemplate");
    } catch(e) { }
    
    this.subscriptionPreviewTemplate = TrimPath.parseDOMTemplate("subscriptionPreviewTemplate");
}

RolloverController.prototype.bindListeners = function() {

    var div = ".showDiv.requiresListeners";

    $(div).bind('mouseenter', function(_event) {

        $(this).find('.play').fadeIn(100, null);
        $(this).find('.info').fadeIn(100, null);

        $(this).oneTime(300, "fadeRolloverTimer", function() {

            if ($(this).children('.rolloverDiv').size() == 0) {
                rolloverController.update($(this));
            }

            $(this).children('.rolloverDiv').fadeIn(300, null);

            var window_w = $(window).width();
            var window_h = $(window).height();

            var y_ofs = $(window).scrollTop();

            var content_w = $(this).find('.rolloverContent').width();
            var content_h = $(this).find('.rolloverContent').height();

            var arrow_w = ($.browser.msie && $.browser.version == 6) ? 0 : 30; //$(this).find('.rolloverArrowRight').width();
            var arrow_h = 74; //$(this).find('.rolloverArrowRight').height();

            var image_w = $(this).width();
            var image_h = $(this).height();

            var image_top = $(this).position().top;
            var image_left = $(this).position().left;

            var x;
            if ((image_left + image_w) + (content_w + arrow_w) > window_w) {

                x = -(content_w + arrow_w);

                $(this).find('.rolloverArrowRight').show();
                $(this).find('.rolloverArrowLeft').hide();

            } else {
                x = image_w + arrow_w;
            }

            var y = (image_h - content_h) / 2;

            // rollover too high
            if ((image_top - y_ofs) + y < 0) {
                y = -(image_top - y_ofs) + PADDING;
                if (y > 0) {
                    // rollover off screen
                    y = 0;
                }
            }

            // rollover too low
            if ((image_top - y_ofs) + (y + content_h) > window_h) {

                var dif = ((image_top - y_ofs) + (arrow_h + PADDING + 17)) - window_h;
                if (dif > 0) {
                    // rollover off screen
                    y = -((image_top - y_ofs) - ((window_h - content_h) + (dif)));
                } else {
                    y = -((image_top - y_ofs) - (window_h - content_h - PADDING));
                }
            }

            $(this).find('.rolloverDiv').css('left', x + 'px');
            $(this).find('.rolloverDiv').css('top', y + 'px');

            var arrow_y = (-y) + ((image_h - arrow_h) / 2);
            $(this).find('.rolloverArrow').css('top', arrow_y + 'px');
        });
    });

    $(div).bind('mouseleave', function(_event) {

        $(this).find('.play').hide();
        $(this).find('.info').hide();

        $(this).stopTime("fadeRolloverTimer");
        $(this).children('.rolloverDiv').hide();
    });


    var subscriptionIconDiv = ".subscriptionIcon.requiresListeners";

    $(subscriptionIconDiv).bind('mouseenter', function(_event) {

        var show;
        $(this).parents().each(function() {
            if ($(this).hasClass('subscriptionPreview')) {
                show = pageModel.getShow($(this).attr('show'));
            }
        });

        if (this.subscriptionPreviewTemplate == null)
            this.subscriptionPreviewTemplate = TrimPath.parseDOMTemplate("subscriptionPreviewTemplate");

        if ($(this).find('.popup').length == 0) {
            var html = this.subscriptionPreviewTemplate.process(null);
            $(this).prepend(html);
        }

        switch ($(this).attr('type')) {
            case "searchSubscription":

                var searchHtml = new StringBuilder();
                for (var i = 0; i < show.SearchQueries.length; i++) {
                    searchHtml.append("<div>Query: " + show.SearchQueries[i] + "</div>");
                }

                $(this).find('.info').html(searchHtml.toString());
                break;

            case "showSubscription":
                var showString = subscriptionController.getShowSubscriptionText(show);
                $(this).find('.info').html(showString);
                break;

            case "episodeSubscription":
                break;
        }

        $(this).find('.popup').show();
        $(this).find('.container').css("top", -$(this).find('.container').height() + "px");
    });

    $(subscriptionIconDiv).bind('mouseleave', function(_event) {
        $(this).find(".popup").hide();
    });

    $(div).removeClass('requiresListeners');
    $(subscriptionIconDiv).removeClass('requiresListeners');
}

RolloverController.prototype.updateNew = function() {

    $(".showDiv.requiresListeners").each(function(){
        rolloverController.update($(this));
    });
}

RolloverController.prototype.update = function (_div) {

    var episode = pageModel.getEpisode(_div.attr('episode'));
    var show = pageModel.getShow(_div.attr('show'));

    var episodes = [];
    if (_div.parents().hasClass('searchResult')) {

        var html = this.searchResultRolloverTemplate.process(episode);
        _div.prepend(html);

        episodes = pageModel.getPageEpisodesForShow(show.Slug);

        var episodesHtml = new StringBuilder();
        for (var i = 0; i < episodes.length; i++) {
            if (i < MAX_SEARCH_EPISODES) {
                episodesHtml.append(this.searchResultEpisodeRolloverTemplate.process(episodes[i]));
            }
        }

        _div.find('.searchResultEpisodes').html(episodesHtml.toString());

        if (episodes.length > MAX_SEARCH_EPISODES) {
            _div.find('.searchResultEpisodes').append("<div><a href='" + show.Path + "' class='small' style='text-decorations: none;'>view more results</a></div>");
        }

    } else {

        var html = this.showRolloverTemplate.process(episode);
        _div.prepend(html);

        episodes.push(episode);

        if (episode.IsNewest) {
            _div.find("#selectedEpisodeText").html("Newest Episode: ");
        }
    }

    var userViewable = true;

    for (var i = 0; i < episodes.length; i++) {
        subscriptionController.updateSubscription(episodes[i]);
        ratingController.updateRatings(episodes[i]);
        favoriteController.updateFavorite(episodes[i]);
        if (episodes[i].IsUserViewable == false) {
            userViewable = false;
        }
    }

    ratingController.updateRatings(show);
    favoriteController.updateFavorite(show);

    ratingController.bindListeners();
    favoriteController.bindListeners();

    this.updateHud(show);

    if (show.IsUserViewable == false) {
        userViewable = false;
    }

    if (userViewable) {
        $('.' + show.Slug + '_explicitMessage').remove();
    } else {
        $('.' + show.Slug + '_playControls').remove();
    }
}

RolloverController.prototype.play = function(_episodeSlug, _div) {

    var channelSlug = "";
    $(_div).parents().each(function() {
        if($(this).hasClass('.playlistChannelEpisode')) {            
            channelSlug = collectionWidget.getCurrentChannelSlug();    
        }
    });
    
    if (channelSlug) {
    
	    MediaPlayer.popupEpisode(_episodeSlug, channelSlug);

    } else {
    
		var episode = pageModel.getEpisode(_episodeSlug);
	    MediaPlayer.popupShowEpisode(_episodeSlug, episode.Show.Slug);
    }

}

RolloverController.prototype.updateHud = function(_object) {

    var w = (_object.Media != "audiovideo") ? 10 : 24;
    $('.' + _object.Slug + '_' + _object.Type + '_mediaImage').width(w);
}

/* BEGIN: common/page_controller */

var THUMBS = "thumbs";
var DETAILS = "details";
var DATE_ASCENDING = "date_asc";
var DATE_DESCENDING = "date_desc";
var TITLE_ASCENDING = "title_asc";
var TITLE_DESCENDING = "title_desc";

function PageController()
{
    this.pageView = new PageView();
    $('.removeMe').remove();
}

PageController.prototype.init = function(_globalPageVModel) {

	this.globalPageVModel = _globalPageVModel;
}

/***************************************************************
 * Global Methods
 ***************************************************************/ 

PageController.prototype.isUser = function() {

	return (this.globalPageVModel.UserType == USER);
}

PageController.prototype.getCurrentUrl = function() {

	return this.globalPageVModel.CurrentUrl;
}




/***************************************************************
 * Toggle Results
 ***************************************************************/

PageController.prototype.viewMediaType = function(_type) {

    $('.dropdown').find('.options').hide();

    if (_type == AUDIO_FLAG) {
        window.location = window.location.pathname + $.query.set('mt', 'audio');
    } else if (_type == VIDEO_FLAG) {
        window.location = window.location.pathname + $.query.set('mt', 'video');
    } else {
        window.location = window.location.pathname + $.query.REMOVE('mt');
    }
}

PageController.prototype.toggleView = function(_view) {

    SettingsManager.setValue("pageview", _view);
    window.location.reload();
}

PageController.prototype.sortBy = function(_type) {
    
    window.location = window.location.pathname + $.query.set('sortby', _type);
}

PageController.prototype.toggleShowDescription = function(_slug){
    this.pageView.toggleShowDescription(_slug);
}

/* BEGIN: common/page_view */

var VIEW_DETAILS = "/images/common/view_details.gif",
    VIEW_THUMBS = "/images/common/view_thumb.gif";

function PageView()
{
    this.updateToggleIcon();
    this.initShowToggle();
}

PageView.prototype.updateToggleIcon = function() {

    if(SettingsManager.getValue("pageview") == "details") {
        $('#resultsViewDropdownImage').attr('src', VIEW_DETAILS);
    } else {
        $('#resultsViewDropdownImage').attr('src', VIEW_THUMBS);
    }    
    
    var query = window.location.search;    
    if(query.indexOf("mt=audio") != -1) {
        $('#mediaType').attr('src', '/images/common/view_audio.gif');
    } else if(query.indexOf("mt=video") != -1) {
        $('#mediaType').attr('src', '/images/common/view_video.gif');
    }

    if(query.indexOf("sortby=date_desc") != -1) {
        $('#sortByType').html('Date (Desc)');
    } else if(query.indexOf("sortby=date_asc") != -1) {
        $('#sortByType').html('Date (Asc)');
    } else if(query.indexOf("sortby=title_asc") != -1) {
        $('#sortByType').html('Title (Asc)');
    } else if(query.indexOf("sortby=title_desc") != -1) {
        $('#sortByType').html('Title (Desc)');
    }
    
    $('.dropdown').bind('mouseenter', function(_event) {
        $(this).find('.options').show();
    });

    $('.dropdown').bind('mouseleave', function(_event) {
        $(this).find('.options').hide();
    });
}

PageView.prototype.initShowToggle = function() {

    $('.showDescription').each(function(){

        var descriptionHeight = $(this).height();
        if (descriptionHeight > SHOW_DESCRIPTION_HEIGHT) {
            $(this).height(SHOW_DESCRIPTION_HEIGHT);
            $(this).next().css('display', '');
        } else {
            $(this).next().remove();
        }
    });
}

PageView.prototype.toggleShowDescription = function(_slug) {
    
    $('.showDescription.Show_' + _slug + '_description').each(function(){

        var descriptionHeight = $(this).height();
        if (descriptionHeight <= SHOW_DESCRIPTION_HEIGHT) {
        
            $(this).css('height', '');
            $(this).next().find('img').attr('src', LESS_ICON);
            $(this).next().find('span').html('less');
            
        } else {

            $(this).height(SHOW_DESCRIPTION_HEIGHT);
            $(this).next().find('img').attr('src', MORE_ICON);
            $(this).next().find('span').html('more');
        }
    });
}

/* BEGIN: common/page_model */

function PageModel()
{
    this.playlistEpisodes = [];
    this.pageEpisodes = [];
    this.episodes = [];
    
    this.allRootChannelModels = [];
    this.rootChannelModels = [];
}

/***************************************************************
 * All Episodes
 ***************************************************************/ 

PageModel.prototype.removeEpisode = function(_episode) {
    for(var i=0; i < this.episodes.length; i++) {
        if(_episode.Slug == this.episodes[i].Slug) {
            this.episodes.splice(i--, 1);
        }
    }
}

PageModel.prototype.addEpisode = function(_episode) {
    
    for(var i=0; i < this.episodes.length; i++) {
        if(_episode.Slug == this.episodes[i].Slug) {
            return;
        }
    }

    this.episodes.push(_episode);
}

PageModel.prototype.addEpisodes = function(_episodes) {

    for(var i=0; i < _episodes.length; i++) {
        this.addEpisode(_episodes[i]);
    }
}

PageModel.prototype.updateEpisodes = function(_episodes) {

    for(i=0; i < this.episodes.length; i++) {
        for(var j=0; j < _episodes.length; j++) {
            if(this.episodes[i].Slug == _episodes[j].Slug) {
                this.episodes[i] = _episodes[j];
            }
        }
    }
}

PageModel.prototype.getEpisode = function(_slug) {
    
    for(var i=0; i < this.episodes.length; i++) {
        if(this.episodes[i].Slug == _slug)
            return this.episodes[i];
    }
    
    return null;
}

PageModel.prototype.getEpisodeForShow = function(_slug) {

    for(var i=0; i < this.episodes.length; i++) {
        if(this.episodes[i].Show.Slug == _slug)
            return this.episodes[i];
    }
    
    return null;    
}

PageModel.prototype.getEpisodesForShow = function(_slug) {

    var showEpisodes = [];
    for(var i=0; i < this.episodes.length; i++) {
        if(this.episodes[i].Show.Slug == _slug)
            showEpisodes.push(this.episodes[i]);
    }
    
    return showEpisodes;    
}

PageModel.prototype.getEpisodeSlugsForShow = function(_slug) {

    var showEpisodes = [];
    for(var i=0; i < this.episodes.length; i++) {
        if(this.episodes[i].Show.Slug == _slug)
            showEpisodes.push(this.episodes[i].Slug);
    }
    
    return showEpisodes;    
}

PageModel.prototype.getShow = function(_slug) {
    
    for(var i=0; i < this.episodes.length; i++) {
        if(this.episodes[i].Show.Slug == _slug)
            return this.episodes[i].Show;
    }
    
    return null;
}


/***************************************************************
 * Playlist Episodes
 ***************************************************************/ 

PageModel.prototype.removePlaylistEpisode = function(_episode) {
    
    for(var i=0; i < this.playlistEpisodes.length; i++) {
        if(_episode.Slug == this.playlistEpisodes[i].Slug) {
            this.playlistEpisodes.splice(i--, 1);
        }
    }
    
    var removeIt = true;
    for(var i=0; i < this.pageEpisodes.length; i++) {
        if(this.pageEpisodes[i].Slug == _episode.Slug) {
            removeIt = false;
            break;
        }
    }
    
    if(removeIt) {
        this.removeEpisode(_episode);
    }
}

PageModel.prototype.addPlaylistEpisode = function(_episode) {

    for(var i=0; i < this.playlistEpisodes.length; i++) {
        if(_episode.Slug == this.playlistEpisodes[i].Slug) {
            return;
        }
    }

    this.playlistEpisodes.push(_episode);

    this.addEpisode(_episode);
}

PageModel.prototype.addPlaylistEpisodes = function(_episodes) {

    for(var i=0; i < _episodes.length; i++) {
        this.addPlaylistEpisode(_episodes[i]);
    }
}

PageModel.prototype.playlistContainsEpisode = function(_slug) {

    for(var i=0; i < this.playlistEpisodes.length; i++) {
        if(_slug == this.playlistEpisodes[i].Slug) {
            return true;
        }
    }
    
    return false;
}

PageModel.prototype.playlistContainsShow = function(_slug) {

    for(var i=0; i < this.playlistEpisodes.length; i++) {
        if(_slug == this.playlistEpisodes[i].Show.Slug) {
            return true;
        }
    }
    
    return false;
}


/***************************************************************
 * Page Episodes
 ***************************************************************/ 

//Includes only page episodes, not widget episodes
PageModel.prototype.addPageEpisode = function(_episode) {

    for(var i=0; i < this.pageEpisodes.length; i++) {
        if(_episode.Slug == this.pageEpisodes[i].Slug) {
            return;
        }
    }

    this.pageEpisodes.push(_episode);

    this.addEpisode(_episode);
}

PageModel.prototype.addPageEpisodes = function(_episodes) {

    for(var i=0; i < _episodes.length; i++) {
        this.addPageEpisode(_episodes[i]);
    }
}

PageModel.prototype.replacePageEpisodes = function(_episodes) {

    this.episodes = [];
    this.pageEpisodes = [];
    this.addPageEpisodes(_episodes);
    this.addEpisodes(this.playlistEpisodes);
}

PageModel.prototype.getPageEpisodesForShow = function(_slug) {

    var showEpisodes = [];
    for(var i=0; i < this.pageEpisodes.length; i++) {
        if(this.pageEpisodes[i].Show.Slug == _slug)
            showEpisodes.push(this.pageEpisodes[i]);
    }
    
    return showEpisodes;    
}

/***************************************************************
 * Channels
 ***************************************************************/ 

PageModel.prototype.addRootChannelModels = function(_rootChannelModels) {

	this.rootChannelModels = _rootChannelModels;
}

PageModel.prototype.addChannelModel = function(_channelModel, _parentChannelSlug) {

	if (isNullOrEmpty(_parentChannelSlug)) {
		this.rootChannelModels.push(_channelModel);
		this.rootChannelModels.sort(this.sortChannel);
	} else {
		var parentChannel = this.getChannelModel(_parentChannelSlug);
		parentChannel.SubChannels.push(_channelModel);
		parentChannel.SubChannels.sort(this.sortChannel);
	}
}

PageModel.prototype.sortChannel = function(x, y) {

	if (isSpecialChannel(x.Slug))
		return 1;

	if (isSpecialChannel(y.Slug))
		return -1;
		
	if (isNullOrEmpty(x.Position) && isNullOrEmpty(y.Position))
		return (x.Name < y.Name) ? -1 : 1;

	if (x.Position >= 0 && y.Position >= 0)
		return (x.Position - y.Position);
	
	return (y.Position >= 0) ? 1 : -1;
}

PageModel.prototype.getChannelModel = function(_slug) {

	return this.getChannel(this.rootChannelModels, _slug);
}

PageModel.prototype.getChannel = function(_models, _slug) {
	
	for (var i=0; i < _models.length; i++) {
	
		if (_models[i].Slug == _slug) {
		
			return _models[i];
			
		} else if (_models[i].SubChannels.length > 0) {
		
		    var match = this.getChannel(_models[i].SubChannels, _slug);
		    if (match != null)
				return match;
		}
	}
	
	return null;
}

PageModel.prototype.getRootChannelModels = function() {
	return this.rootChannelModels;
}

PageModel.prototype.getMyRootChannelModels = function() {

	var myRootChannelModels = [];
	
	for (var i=0; i < this.rootChannelModels.length; i++) {
		if (!isSpecialChannel(this.rootChannelModels[i].Slug))
			myRootChannelModels.push(this.rootChannelModels[i]);
	}
	
	return myRootChannelModels;
}

PageModel.prototype.replaceChannelModel = function(_channelSlug, _channelModel) {
	
	this.removeChannelModel(_channelSlug);
	this.addChannelModel(_channelModel, _channelModel.ParentChannelSlug);
}

PageModel.prototype.removeChannelModel = function(_channelSlug) {

	var channelModel = this.getChannelModel(_channelSlug);

	var channelModels = [];
	if (isNullOrEmpty(channelModel.ParentChannelSlug)) {
		channelModels = this.rootChannelModels;
	} else {
		var parentChannelModel = this.getChannelModel(channelModel.ParentChannelSlug);
		channelModels = parentChannelModel.SubChannels;
	}

	for (var i=0; i < channelModels.length; i++) {
		if (channelModels[i].Slug == channelModel.Slug) {
			channelModels.splice(i, 1);
			return;
		}
	}
}

/* BEGIN: common/paging_controller */

var PAGING_MAX = 20;

var MORE_ARROW_ICON     = "/images/showpage/blue_more_arrow.gif",
    LESS_ARROW_ICON     = "/images/showpage/blue_less_arrow.gif";

function PagingController() {
    try {
        this.pagingTemplate = TrimPath.parseDOMTemplate("pagingTemplate");
    } catch (e) {        
    }
}

PagingController.prototype.init = function(_controller) {
this.controller = _controller;
    
}

PagingController.prototype.updatePaging = function(_pagingModel) {

    this.pagingModel = _pagingModel;
    this.page = _pagingModel.Page;
    
    var pagingObject = {
        pages : new Array()
    }
        
    var min = ((Math.ceil(this.page / PAGING_MAX) - 1) * PAGING_MAX) + 1;
    var max = (_pagingModel.Pages > min + (PAGING_MAX-1)) ? min + (PAGING_MAX-1) : _pagingModel.Pages;
    
    for(var i=min; i <= max; i++) {
        var page = {
            number : this.pagingModel.TimelineOrdering ? ((min+max)-i) : i,
            width : (420 / ((max-min)+1)) - 2
        };
        
        pagingObject.pages.push(page);
    }
    
    var pagingHtml = this.pagingTemplate.process(pagingObject);
    $('.paging').html(pagingHtml);
    
    $('.' + this.page + '_page').css("background", "#8c90d6").css("border", "solid 1px #3e44b6");

    var farLeftPage = (this.pagingModel.TimelineOrdering) ? this.pagingModel.Pages : 1;
    if((this.pagingModel.TimelineOrdering) ? max : min == farLeftPage) {
        $('.lessArrow').hide();
    } else {
        $('.lessArrow').show();
    }
    
    if(this.page == farLeftPage) {
        $('.olderEpisodes').hide();
        $('.olderEpisodesInactive').show();
    } else {
        $('.olderEpisodes').show();
        $('.olderEpisodesInactive').hide();
    }
        
    var farRightPage = (this.pagingModel.TimelineOrdering) ? 1 : this.pagingModel.Pages;
    if(this.page == farRightPage) {
        $('.newerEpisodes').hide();
        $('.newerEpisodesInactive').show();
    } else {
        $('.newerEpisodes').show();
        $('.newerEpisodesInactive').hide();
    }
    
    if((this.pagingModel.TimelineOrdering) ? min : max == farRightPage) {
        $('.moreArrow').hide();
    } else {
        $('.moreArrow').show();        
    }
}

PagingController.prototype.farLeft = function() {
    var page = this.pagingModel.TimelineOrdering ? this.pagingModel.Pages : 1;
    this.pagingNumber(page);
}

PagingController.prototype.left = function() {
    var page = this.pagingModel.TimelineOrdering ? this.page+1 : this.page-1;
    this.pagingNumber(page);
}

PagingController.prototype.farRight = function() {
    var page = this.pagingModel.TimelineOrdering ? 1 : this.pagingModel.Pages;
    this.pagingNumber(page);
}

PagingController.prototype.right = function() {
    var page = this.pagingModel.TimelineOrdering ? this.page-1 : this.page+1;
    this.pagingNumber(page);
}

PagingController.prototype.pagingNumber = function(_num) {

    if(this.controller && this.controller.pagingNumber) {
        this.controller.pagingNumber(_num);
    } else {
    
        if (window.location.search) {
            var queries = (window.location.search.replace('?', '')).split("&");
            
            var location = window.location.pathname + "?";
            for(var i=0; i < queries.length; i++) {
                if(queries[i].indexOf("p=") == -1) {
                    location += queries[i] + "&";
                }
            }
            window.location = location + "p=" + _num;
        } else {
            window.location = window.location.pathname + "?p=" + _num;
        }
    }
}

/* BEGIN: common/rss_controller */

function RssController()
{
}

RssController.prototype.init = function(_globalPageVModel) {

    this.PrivateRss = _globalPageVModel.PrivateRss;
    this.PublicRss = _globalPageVModel.PublicRss;
}

RssController.prototype.launch = function (_type, _channelSlug, _public) {

    selectedChannel = pageModel.getChannelModel(_channelSlug);

	try {

        if (_type == ZUNE) {

            var link = this.PrivateRss.remove("http");
            window.location = "zune://subscribe/?" + selectedChannel.Name + " (via Mediafly)=" + link + "/" + selectedChannel.Path;

        } else if (_type == ITUNES) {

            var link = this.PrivateRss.replace("http", "itpc");
            window.location = link + "/" + selectedChannel.Path;

        } else if (_type == WINAMP) {

            var link = this.PrivateRss.replace("http", "pcast");
            link = "winamp://Podcast/Subscribe?url=" + link + "/" + selectedChannel.Path;
            window.location = link;

        } else if (_type == RSS) {

            var link = this.PrivateRss;
            if (_public) {
                link = this.PublicRss;
            }

            if (isSpecialChannel(selectedChannel.Slug)) {
                if (selectedChannel.Slug != ALL_CHANNEL_SLUG) {
                    link += "/" + selectedChannel.Slug;
                }
            } else {
                link += "/" + selectedChannel.Path;
            }

            window.open(link, "RSS");
        } 
    }
    catch (e) {
    }

}

/* BEGIN: plugins/jquery.query-2.1.7 */

/**
 * jQuery.query - Query String Modification and Creation for jQuery
 * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
 * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
 * Date: 2009/8/13
 *
 * @author Blair Mitchelmore
 * @version 2.1.7
 *
 **/
new function(settings) { 
  // Various Settings
  var $separator = settings.separator || '&';
  var $spaces = settings.spaces === false ? false : true;
  var $suffix = settings.suffix === false ? '' : '[]';
  var $prefix = settings.prefix === false ? false : true;
  var $hash = $prefix ? settings.hash === true ? "#" : "?" : "";
  var $numbers = settings.numbers === false ? false : true;
  
  jQuery.query = new function() {
    var is = function(o, t) {
      return o != undefined && o !== null && (!!t ? o.constructor == t : true);
    };
    var parse = function(path) {
      var m, rx = /\[([^[]*)\]/g, match = /^([^[]+)(\[.*\])?$/.exec(path), base = match[1], tokens = [];
      while (m = rx.exec(match[2])) tokens.push(m[1]);
      return [base, tokens];
    };
    var set = function(target, tokens, value) {
      var o, token = tokens.shift();
      if (typeof target != 'object') target = null;
      if (token === "") {
        if (!target) target = [];
        if (is(target, Array)) {
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        } else if (is(target, Object)) {
          var i = 0;
          while (target[i++] != null);
          target[--i] = tokens.length == 0 ? value : set(target[i], tokens.slice(0), value);
        } else {
          target = [];
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        }
      } else if (token && token.match(/^\s*[0-9]+\s*$/)) {
        var index = parseInt(token, 10);
        if (!target) target = [];
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else if (token) {
        var index = token.replace(/^\s*|\s*$/g, "");
        if (!target) target = {};
        if (is(target, Array)) {
          var temp = {};
          for (var i = 0; i < target.length; ++i) {
            temp[i] = target[i];
          }
          target = temp;
        }
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else {
        return value;
      }
      return target;
    };
    
    var queryObject = function(a) {
      var self = this;
      self.keys = {};
      
      if (a.queryObject) {
        jQuery.each(a.get(), function(key, val) {
          self.SET(key, val);
        });
      } else {
        jQuery.each(arguments, function() {
          var q = "" + this;
          q = q.replace(/^[?#]/,''); // remove any leading ? || #
          q = q.replace(/[;&]$/,''); // remove any trailing & || ;
          if ($spaces) q = q.replace(/[+]/g,' '); // replace +'s with spaces
          
          jQuery.each(q.split(/[&;]/), function(){
            var key = decodeURIComponent(this.split('=')[0] || "");
            var val = decodeURIComponent(this.split('=')[1] || "");
            
            if (!key) return;
            
            if ($numbers) {
              if (/^[+-]?[0-9]+\.[0-9]*$/.test(val)) // simple float regex
                val = parseFloat(val);
              else if (/^[+-]?[0-9]+$/.test(val)) // simple int regex
                val = parseInt(val, 10);
            }
            
            val = (!val && val !== 0) ? true : val;
            
            if (val !== false && val !== true && typeof val != 'number')
              val = val;
            
            self.SET(key, val);
          });
        });
      }
      return self;
    };
    
    queryObject.prototype = {
      queryObject: true,
      has: function(key, type) {
        var value = this.get(key);
        return is(value, type);
      },
      GET: function(key) {
        if (!is(key)) return this.keys;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        while (target != null && tokens.length != 0) {
          target = target[tokens.shift()];
        }
        return typeof target == 'number' ? target : target || "";
      },
      get: function(key) {
        var target = this.GET(key);
        if (is(target, Object))
          return jQuery.extend(true, {}, target);
        else if (is(target, Array))
          return target.slice(0);
        return target;
      },
      SET: function(key, val) {
        var value = !is(val) ? null : val;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        this.keys[base] = set(target, tokens.slice(0), value);
        return this;
      },
      set: function(key, val) {
        return this.copy().SET(key, val);
      },
      REMOVE: function(key) {
        return this.SET(key, null).COMPACT();
      },
      remove: function(key) {
        return this.copy().REMOVE(key);
      },
      EMPTY: function() {
        var self = this;
        jQuery.each(self.keys, function(key, value) {
          delete self.keys[key];
        });
        return self;
      },
      load: function(url) {
        var hash = url.replace(/^.*?[#](.+?)(?:\?.+)?$/, "$1");
        var search = url.replace(/^.*?[?](.+?)(?:#.+)?$/, "$1");
        return new queryObject(url.length == search.length ? '' : search, url.length == hash.length ? '' : hash);
      },
      empty: function() {
        return this.copy().EMPTY();
      },
      copy: function() {
        return new queryObject(this);
      },
      COMPACT: function() {
        function build(orig) {
          var obj = typeof orig == "object" ? is(orig, Array) ? [] : {} : orig;
          if (typeof orig == 'object') {
            function add(o, key, value) {
              if (is(o, Array))
                o.push(value);
              else
                o[key] = value;
            }
            jQuery.each(orig, function(key, value) {
              if (!is(value)) return true;
              add(obj, key, build(value));
            });
          }
          return obj;
        }
        this.keys = build(this.keys);
        return this;
      },
      compact: function() {
        return this.copy().COMPACT();
      },
      toString: function() {
        var i = 0, queryString = [], chunks = [], self = this;
        var encode = function(str) {
          str = str + "";
          if ($spaces) str = str.replace(/ /g, "+");
          return encodeURIComponent(str);
        };
        var addFields = function(arr, key, value) {
          if (!is(value) || value === false) return;
          var o = [encode(key)];
          if (value !== true) {
            o.push("=");
            o.push(encode(value));
          }
          arr.push(o.join(""));
        };
        var build = function(obj, base) {
          var newKey = function(key) {
            return !base || base == "" ? [key].join("") : [base, "[", key, "]"].join("");
          };
          jQuery.each(obj, function(key, value) {
            if (typeof value == 'object') 
              build(value, newKey(key));
            else
              addFields(chunks, newKey(key), value);
          });
        };
        
        build(this.keys);
        
        if (chunks.length > 0) queryString.push($hash);
        queryString.push(chunks.join($separator));
        
        return queryString.join("");
      }
    };
    
    return new queryObject(location.search, location.hash);
  };
}(jQuery.query || {}); // Pass in jQuery.query as settings object


