if(typeof Vodspot == "undefined")
  var Vodspot = {};

//=========
//= Util =
//=========

(function($) {
  $.vp = $.vp || {};
  
  $.vp.busyForm = function(elt) {
    Vodspot._save_busy = elt;
    $(elt).css({opacity:0.5}).attr('busy', 'true');
    document.body.style.cursor = 'wait';
  }
  
  $.vp.ajaxComplete = function() {
    document.body.style.cursor = '';
    if (Vodspot._save_busy) {
      $(Vodspot._save_busy).css({opacity:''}).removeAttr('busy');
      Vodspot._save_busy = null;
    }
  }
  
  $.vp.ajaxError = function(event, request) {
    $.vp.ajaxComplete();
    var msg = "Sorry, an error occurred. You might want to try that action again.";
    if (request.responseText.length < 500) {
      msg = request.responseText;
    }
    alert(msg);
  }
  
  $.vp.postForm = function(url, form, options) {
    options = options || {};
    $.ajax({
      type: 'post',
      url: url,
      data: form.serialize(),
      dataType: options['dataType'] || 'json',
      beforeSend: function() {$.vp.busyForm(form)},
      success: function(result) {
        if (options.success) {
          try {
            options.success(result, form);
          } catch(e) {
            $.vp.logError(e);
          }
        }
      }
    });

    $.vp.logError = function(exception) {
      if (console) {
        console.log(exception);
      }
    }
  }
})(jQuery);


// ========
// = Tabs =
// ========
(function($) {
  $.fn.tabs = function(options) {
    return this.each(function() {
      return new $.tabs(this, options);
    });    
  };
  
  $.tabs = function(el, options) {
    var defaults = {tabSelector: '.tab',
                    tabContainerStyle: {
                      borderBottom:'1px solid #ccc',
                      height:35,
                      marginBottom:5,
                      paddingLeft:5
                    },
                    tabStyle: {
                      background:'url(/images/hosted/tab_gradient_50px.png)',
                      borderWidth:'1px 1px 0 1px',
                      borderStyle:'solid',
                      borderColor:'#ccc',
                      cursor:'pointer',
                      float:'left',
                      height:24,
                      marginRight:3,
                      paddingTop:5,
                      paddingBottom:5,
                      paddingRight:10,
                      paddingLeft:10,
                      '-moz-border-radius-topleft':5,
                      '-moz-border-radius-topright':5,
                      '-webkit-border-top-left-radius':5,
                      '-webkit-border-top-right-radius':5
                    },
                    activeTabStyle: {
                      height:25,
                      background:'#fff'
                    }
                  };
    var options = $.extend(true, defaults, options);
    
    var tabs_node = $(el);
    
    // Find each tab
    $.each(tabs_node.find(options.tabSelector),
      function(i, node) {
        var node = $(node);
        
        // Find the tab panel
        findPanel(node).hide();
        
        // Bind click on the tabs
        node.click(function() {showPanel($(this))});
      }
    );
    
    // Stylize the tabs container
    tabs_node.css(options.tabContainerStyle);
    
    // Stylize the tabs
    tabs_node.find(options.tabSelector).
      css(options.tabStyle);
    tabs_node.find('.tab:last').after('<div style="clear:both;"></div>');

    // Show the first tab
    showPanel(tabs_node.find('.tab:first'));
    
    function findPanel(tab) {
      return $(tab.attr('rel'));
    }
    
    function showPanel(tab) {
      // Find active tab
      var active_tab = tabs_node.find('.tab.active');
      $(active_tab).removeClass('active').
        css(options.tabStyle);
      if (active_tab.attr('rel')) {
        // Hide active tab panel
        findPanel(active_tab).hide();
      }
      
      // Set the tab to active
      tab.addClass('active').
        css(options.activeTabStyle);
      
      // Show the panel
      var panel = findPanel(tab);
      panel.fadeIn();
    }
  }
})(jQuery);

// =============================
// = Share This Video Dropdown =
// =============================
(function($) {
  $.fn.video_share = function(options) {
    return this.each(function() {
      return new $.video_share(this, options);
    });
  };
  
  var defaults = {targets: ['vodpod', 'facebook', 'twitter', 'myspace', 'wordpress', 'blogger', 'typepad', 'tumblr', 'embed'],
                  css: {
                    container: {cursor:'pointer'},
                    icon: {verticalAlign:'middle'},
                    share: {paddingLeft:4},
                    arrow: {paddingLeft:4, verticalAlign:'middle'},
                    menu: {position:'absolute', border:'1px solid #ccc', width:'150px', background:'#eee', zIndex:5},
                    target: {padding:'5px 10px', borderBottom:'1px dotted #ccc', cursor:'pointer', height: 16, lineHeight:'15px'}
                  }};
  
  $.video_share = function(el, options) {
    var options = $.extend(true, defaults, options);
    var target_defs = {vodpod: ['Vodpod', shareVodpod],
                       facebook: ['Facebook', shareFacebook],
                       twitter: ['Twitter', shareTwitter],
                       myspace: ['Myspace', shareMyspace],
                       wordpress: ['Wordpress', shareWordpress],
                       blogger: ['Blogger', shareBlogger],
                       typepad: ['Typepad', shareTypepad],
                       tumblr: ['Tumblr', shareTumblr],
                       embed: ['Embed Code', shareEmbed]};
    
    // Build the share button
    var node = $(el).
      append($(document.createElement('img')).attr('src', '/images/icon_versions/22/share_video.png').css(options.css.icon)).
      append($(document.createElement('b')).text('share').css(options.css.share)).
      append($(document.createElement('img')).attr('src', '/images/down_arrow_2.png').addClass('arrow').css(options.css.arrow)).
      css(options.css.container).
      addClass('video_share');
    
    //Build the share dropdown
    var menu_node = $(el).
      parent().
      append($(document.createElement('div')).
             addClass('share_video_menu').
             css(options.css.menu).
             hide()).
      find('.share_video_menu');
    
    // Close the dropdown when user clicks something else
    $(document).click(hideShareDropdown);
    
    // Create the targets
    $(options.targets).each(function(i, key) {
      var target = target_defs[key];
      var target_node = $(document.createElement('div')).
        text(target[0]).
        addClass('target').
        css(options.css.target).
        click(target[1]).
        appendTo(menu_node);
      
      // target hovering
      target_node.hover(function() {$(this).css({background:'#fff'})},
                        function() {$(this).css({background:null})});

      // Create the img
      $(document.createElement('img')).
        attr('src', 'http://assets.vpimg.net/images/share_icons/' + key + '.png').
        css({paddingRight:10, verticalAlign:'middle'}).
        prependTo(target_node);
    });
    
    // Bind the share dropdown to the element
    $(el).click(showShareDropdown);
    
    function showShareDropdown(event) {
      event.preventDefault();
      event.stopPropagation();
      
      // Get the share link coordinates
      var top  = $(el).position().top;
      var left = $(el).position().left;
      
      menu_node.css({top:(top + $(el).outerHeight()), left:left});
      menu_node.toggle(150);
    }

    function hideShareDropdown(event) {
      menu_node.hide(150);
    }
    
    function shareVodpod(event) {
      event.preventDefault();
      
      url = 'http://vodpod.com/account/add_video_page?p=' + escape(options.video_url);
      window.open(url);
    }
    
    function shareFacebook(event) {
      event.preventDefault();

      url = 'http://www.facebook.com/sharer.php?u=' + escape(options.video_url)
      popup = window.open(url,'facebookShare','height=400,width=600');
      if (window.focus) {popup.focus()}
    }

    function shareTwitter(event) {
      event.preventDefault();
      
      message = encodeURIComponent("Watching " + options.video_title + " at Vodpod " + options.video_url);
      url = "http://twitter.com/home?status=" + message;
      popup = window.open(url,'twitterShare','height=500,width=800,scrollbars=1');
      if (window.focus) {popup.focus()};
    }

    function shareMyspace(event) {
      event.preventDefault();
      
      var targetUrl = "http://www.myspace.com/Modules/PostTo/Pages/?";
      targetUrl += "t=" + encodeURIComponent(options.video_title);
      targetUrl += "&c=" + encodeURIComponent(options.video_embed);
      targetUrl += "&u=" + encodeURIComponent(options.video_url);
      targetUrl += "&l=2";
      window.open(targetUrl);
    }

    function shareWordpress(event) {
      event.preventDefault();
      postToBlog('wordpress.com');
    }

    function shareBlogger(event) {
      event.preventDefault();
      postToBlog('blogger');
    }

    function shareTypepad(event) {
      event.preventDefault();
      postToBlog('typepad');
    }

    function shareTumblr(event) {
      event.preventDefault();
      postToBlog('tumblr');
    }

    function shareEmbed(event) {
      event.preventDefault();
      content = '<textarea style="border:1px solid #999;width:300px;height:75px;" onclick="this.select()">' + options.video_embed + '</textarea>';
      new Vodspot.Popup({
        title:'Embed Code',
        data:content,
        buttons: [Vodspot.Buttons.close],
        height:180,
        width:350
      })
    }
    
    function postToBlog(blog) {
      // options.video_url = 'http://vodpod.com/watch/19517-flying-dude';
      url = 'http://vodpod.com/account/save_video?dest=blog,' + blog + "&p=" + options.vodpod_url + "&noframe=true&src=video";
      popup = window.open(url,'blogShare','height=540,width=660,scrollbars=1');
      if (window.focus) {popup.focus()};
    }
  };
})(jQuery);

// ==================
// = Voting Buttons =
// ==================
(function($) {
  $.fn.video_vote = function(options) {
    return this.each(function() {
      return new $.video_vote(this, options);
    });
  };
  
  var defaults = {up_votes:0,
                  down_votes:0,
                  css: {
                    container: {width:125, height:32, position:'relative'}
                  }};
  
  $.video_vote = function(el, options) {
    var options = $.extend(true, defaults, options);

    // Build the voting links
    var node = $(el).
      addClass('video_vote').
      css(options.css.container).
      append($(document.createElement('div')).
             addClass('up_votes_count').
             text(options.up_votes).
             css({position:'absolute', right:80, top:5})).
      append($(document.createElement('img')).
             addClass('up_vote').
             attr('src', '/images/icon_versions/22/thumbs_up_off.png').
             css({position:'absolute', right:50, cursor:'pointer'})).
      append($(document.createElement('img')).
             addClass('down_vote').
             attr('src', '/images/icon_versions/22/thumbs_down_off.png').
             css({position:'absolute', right:25, cursor:'pointer'})).
      append($(document.createElement('div')).
             addClass('down_votes_count').
             text(options.down_votes).
             css({position:'absolute', left:110, top:5}))
    
    // Setup up vote button
    $(el).find('.up_vote').
      click(vote_up).
      hover(function() {$(this).attr('src', '/images/icon_versions/22/thumbs_up_on.png')},
            function() {$(this).attr('src', '/images/icon_versions/22/thumbs_up_off.png')});
      

    // Setup down vote button
    $(el).find('.down_vote').
      click(vote_down).
      hover(function() {$(this).attr('src', '/images/icon_versions/22/thumbs_down_on.png')},
            function() {$(this).attr('src', '/images/icon_versions/22/thumbs_down_off.png')});
    
    function vote_up(event) {
      event.preventDefault();
      $(this).fadeTo(200, 0.5);
      
      $.post('/hosted/vote_video_up.js',
             {video_key: options.video_key, collection_key: options.collection_key},
             function(data) {
               $('.up_vote').fadeTo(200, 1);
               $('.up_votes_count').text(data.up);
             }, 'json');
    }

    function vote_down(event) {
      event.preventDefault();
      $(this).fadeTo(200, 0.5);

      $.post('/hosted/vote_video_down.js',
             {video_key: options.video_key, collection_key: options.collection_key},
             function(data) {
               $('.down_vote').fadeTo(200, 1);
               $('.down_votes_count').text(data.down);
             }, 'json');
    }
  };
})(jQuery);

// ====================
// = Video Commenting =
// ====================
(function($) {
  $.fn.video_comment = function(options) {
    return this.each(function() {
      return new $.video_comment(this, options);
    });
  };
  
  $.video_comment = function(el, options) {
    var defaults = {addCommentCallback: addCommentCallback,
                    commentLabel: 'Leave a comment here',
                    nameLabel: 'Name',
                    emailLabel: 'Email',
                    websiteLabel: 'Website URL',
                    form_node: null};
    var options = $.extend(defaults, options);
    var el = $(el);
    var form_node;
    
    // Build out the comment form
    if (options.form_node == null) {
      form_node = $(document.createElement('form')).
        attr('action', '/hosted/ajax_comment.js').
        submit(submitForm);
      // Build the form inputs
      form_node.append($(document.createElement('input')).attr({type: 'hidden', name: 'video_key', value: options.video_key}));
      form_node.append($(document.createElement('input')).attr('type', 'hidden').attr('name', 'collection_key').attr('value', options.collection_key));
      form_node.append($(document.createElement('textarea')).
                       attr('name', 'message').
                       attr('value', options.commentLabel).
                       addClass('message').
                       focus(function() {
                         if (this.value == options.commentLabel) this.value = '';
                       }));
      form_node.append($(document.createElement('input')).
                      attr('type', 'text').
                      attr('value', options.nameLabel).
                      attr('name', 'name').
                      addClass('entrybox').
                      addClass('name').
                      focus(function() {
                        if (this.value == options.nameLabel) this.value = '';
                      }));
      form_node.append($(document.createElement('input')).
                      attr('type', 'text').
                      attr('value', options.emailLabel).
                      attr('name', 'email').
                      addClass('entrybox').
                      addClass('email').
                      focus(function() {
                        if (this.value == options.emailLabel) this.value = '';
                      }));
      form_node.append($(document.createElement('input')).
                      attr('type', 'text').
                      attr('value', options.websiteLabel).
                      attr('name', 'website').
                      addClass('entrybox').
                      addClass('website').
                      focus(function() {
                        if (this.value == options.websiteLabel) this.value = '';
                      }));
      form_node.append($(document.createElement('input')).
                      attr('type', 'image').
                      attr('value', 'Submit').
                      attr('src', '/images/hosted/comment_submit.png').
                      addClass('submit'));
      el.append(form_node);
    } else {
      // Use the supplied form
      form_node = options.form_node;
      
      form_node.
        attr('action', '/hosted/ajax_comment.js').
        submit(submitForm);
    }
    
    function submitForm(event) {
      event.preventDefault();
      if (form_node.attr('busy') == 'true') return false;
      
      if (form_node.find('.message').val() == options.commentLabel || form_node.find('.message').val() == '') {alert('Please enter your comment.'); return false;}
      if (form_node.find('.name').val() == options.nameLabel || form_node.find('.name').val() == '') {alert('Please enter your name.'); return false;}
      if (form_node.find('.email').val() == options.emailLabel || form_node.find('.email').val() == '') {alert('Please enter your email.'); return false;}
      if (form_node.find('.website').val() == options.websiteLabel) {form_node.find('.website').val('')}
      
      $.vp.postForm('/hosted/ajax_comment.js', form_node, {success:options.addCommentCallback});
    }
    
    function addCommentCallback(data, form_node) {
      $(form_node).html('');
      el.find('.list').prepend($(document.createElement('div')).
        addClass('comment').
        html('<a href="' + data.user.url + '" class="thumbnail" rel="nofollow"><img src="' + data.user.thumbnail + '"/></a>' +
             '<div class="content"><a href="' + data.user.url + '" rel="nofollow">' + data.user.name + '</a> &mdash; seconds ago<br/>' + data.text + '</div><div style="clear:both;"></div>')
      );
    }
  }
})(jQuery);

//====================
//= Video Submission =
//====================
(function($) {
  $.fn.video_submission = function(options) {
    return this.each(function() {
      return new $.vp.video_submission(this, options);
    });
  }
 
 $.vp = $.vp || {};
 
 $.vp.video_submission = function(el, options) {
    var defaults = {addVideoCallback: addVideoCallback,
                    embedLabel: 'Enter a video <embed> tag',
                    nameLabel: 'Name*',
                    emailLabel: 'Email*',
                    websiteLabel: 'Website URL',
                    titleLabel: 'Video Title*',
                    commentLabel: 'Your Comment',
                    submitMessage: 'Thanks for your submission! Your video is being reviewed and will be published soon.',
                    embed_field_style: {
                      display:'block',
                      width:'500px',
                      height:'100px',
                      border:'1px solid #CCC',
                      padding:'4px',
                      margin: '4px 0px' 
                    },
                    entrybox_style: {
                      display:'block',
                      width:'500px',
                      border:'1px solid #CCC',
                      padding:'4px',
                      margin: '4px 0px' 
                    },
                    commentbox_style: {
                      display:'block',
                      width:'500px',
                      height:'60px',
                      border:'1px solid #CCC',
                      padding:'4px',
                      margin: '4px 0px 20px 0px' 
                    }
    }
    var options = $.extend(true, defaults, options);
    var el = $(el);
    
    // Build out the comment form
    var form_node = $(document.createElement('form')).
      attr('action', '/hosted/ajax_submitvideo.js').
      submit(submitForm);
    // Build the form inputs
    form_node.append($(document.createElement('textarea')).attr({name: 'embed', value: options.embedLabel}).
                     css(options.embed_field_style).
                     addClass('embed_field').
                     click(function() {
                       if (this.value == options.embedLabel) this.value = '';
                     }));
    
    function show_submit_form() {
      // Add div to hold embed preview
      form_node.append($(document.createElement('div')).attr('id', 'embed_preview').
          css({width:500, height:400, overflow: 'hidden', marginTop: '4px', marginBottom: '10px',border:'1px solid #CCC'}));
      
      form_node.append($(document.createElement('input')).attr({type:'text',value:options.titleLabel, name: 'title'}).
                      css(options.entrybox_style).
                      addClass('entrybox').
                      addClass('title').
                      focus(function() {
                        if (this.value == options.titleLabel) this.value = '';
                      }));
      form_node.append($(document.createElement('textarea')).attr({value:options.commentLabel, name: 'comment'}).
                      css(options.commentbox_style).
                      addClass('commentbox').
                      focus(function() {
                        if (this.value == options.commentLabel) this.value = '';
                      }));
      form_node.append($(document.createElement('input')).attr({type:'text',value:options.nameLabel, name: 'name'}).
                      css(options.entrybox_style).
                      addClass('entrybox').
                      addClass('name').
                      focus(function() {
                        if (this.value == options.nameLabel) this.value = '';
                      }));
      form_node.append($(document.createElement('input')).attr({type:'text',value:options.emailLabel,name:'gopher'}).
                      css(options.entrybox_style).
                      addClass('entrybox').
                      addClass('email').
                      focus(function() {
                        if (this.value == options.emailLabel) this.value = '';
                      }));
      form_node.append($(document.createElement('input')).attr({type: 'text', value: options.websiteLabel, name: 'website'}).
                      css(options.entrybox_style).
                      addClass('entrybox').
                      addClass('website').
                      focus(function() {
                        if (this.value == options.websiteLabel) this.value = '';
                      }));
      form_node.append($(document.createElement('input')).attr({type: 'image', value: 'Submit', 
      	              src: '/images/hosted/comment_submit.png'}).
                      addClass('submit'));
      
      $('#embed_preview').html(form_node.find('.embed_field').val());
      
      return false;
    }
    
    form_node.append($(document.createElement('input')).attr({type: 'image', value: 'Submit', 
      src: '/images/hosted/preview_button.png'}).
      addClass('submit').
      click(show_submit_form));
    
    el.append(form_node);
    
    function submitForm(event) {
      event.preventDefault();
      if (form_node.find('.embed').val() == options.embedLabel || form_node.find('.embed_field').val() == '') {alert('Please enter an embed tag.'); return false;}
      if (form_node.find('.title').val() == options.titleLabel || form_node.find('.title').val() == '') {alert('Please enter the video title.'); return false;}
      if (form_node.find('.name').val() == options.nameLabel || form_node.find('.name').val() == '') {alert('Please enter your name.'); return false;}
      if (form_node.find('.email').val() == options.emailLabel || form_node.find('.email').val() == '') {alert('Please enter your email.'); return false;}
      
      $.vp.postForm('/hosted/ajax_submitvideo.js', form_node, {success:addVideoCallback, dataType:'text'});
    }
    
    function addVideoCallback(message) {
      el.html("<div style=\"padding:20px 10px;border:1px solid #CCC\"><strong>" + options.submitMessage + "</strong></div>")
    }
  }
})(jQuery);

// ===============
// = Ajax Slider =
// ===============
(function($) {
  $.fn.slider = function(options) {
    return new $.slider(this[0], options);
    
    // return new Vodspot.Slider(this[0], options);
  };
  
  $.slider = function(el, options) {
    var slider_node = $(el);

    $.extend(slider_node,
      {
        setupIndices: function() {
          $('li', slider_node).each(function(i, node) {
            $(node).attr('index', first+i);
          })
        },
        
        togglePagination: function() {
          if (first == 0) {
            clip_node.siblings('.paginator_prev').addClass('inactive')
          } else {
            clip_node.siblings('.paginator_prev').removeClass('inactive')
          }
        },
        
        loadNextBatch: function() {
          if(paging_locked) return;

          paging_locked = true;
          animation = (options.direction == 'horizontal') ? {left: "-="+offset} : {top: "-="+offset};
          slider_node.animate(animation, options.delay, 'swing', function() {paging_locked=false;});
          first += options.numItems;

          // Do we need to load a new batch of data?
          if (options.get.ajax && $('li', slider_node).size() - first <= (options.numItems*2)) {
            current_page += 1
            var data = options.get.data;
            data[options.get.page_param || 'page'] = current_page;
            $.get(options.get.url, data, options.get.callback);
          }
          
          slider_node.togglePagination();
        },

        loadPrevBatch: function() {
          if (first <= 0) return;
          if (paging_locked) return;

          paging_locked = true;
          animation = (options.direction == 'horizontal') ? {left: "+="+offset} : {top: "+="+offset};
          slider_node.animate(animation, options.delay, function() {paging_locked=false;});
          first -= options.numItems;

          slider_node.togglePagination();
        },
        
        loadPage: function(page) {
          if (paging_locked) return;

          new_offset = ((page-1)) * offset * -1;
          
          paging_locked = true;
          animation = (options.direction == 'horizontal') ? {left: new_offset} : {top: new_offset};
          slider_node.animate(animation, options.delay, function() {paging_locked=false;});
          current_page = page;
        },
        
        ajaxCallback: function(response) {
          var response = $(response);
          slider_node.append(response);

          var width = $('li', slider_node).size() * $('li', slider_node).outerWidth();
          $(slider_node).
            css({width: width * 1.5});
        }
      }
    )

    var defaults = {
      direction: 'horizontal',
      prevLabel: '&laquo;',
      nextLabel: '&raquo;',
      numItems: 10,
      delay: 500,
      get: {
        ajax: false,
        page_param: 'p',
        callback: slider_node.ajaxCallback
      }
    };
    var options = $.extend(true, defaults, options);
    var first = 0;
    var itemHeight = options.itemHeight || parseInt($('li:first', slider_node).outerHeight());
    var itemWidth = options.itemWidth || parseInt($('li:first', slider_node).outerWidth());
    var offset = (options.direction == 'horizontal') ?
                  itemWidth * options.numItems :
                  itemHeight * options.numItems;
    var current_page = 1
    var paging_locked = false;
    
    // Setup CSS on the slider
    slider_node.css({position:'relative', top: 0, left: 0});
    // If this is a horizontal slider, we need to specify the width of all the elements in the slider
    if (options.direction == 'horizontal')
      slider_node.css({width: 5000});
    
    // Create the clip container, only if it doesn't already exist
    var clip_node = ($(slider_node).parents('.paginator_clip').size() > 0) ?
                    $(slider_node).parents('.paginator_clip') :
                    $(slider_node).wrap('<div class="paginator_clip"></div>').parent();
                    
    // Horiz or veritcal?
    var clip_height = (options.direction == 'horizontal') ? itemHeight : offset;
    var clip_width  = (options.direction == 'horizontal') ? offset : $(slider_node).outerWidth();
    clip_node.css({position:'relative', overflow:'hidden', height:clip_height, width:clip_width});

    // Build the arrows, if they don't already exist
    if (clip_node.siblings('.paginator_prev').size() == 0)
      clip_node.
        before('<div class="paginator_prev">' + options.prevLabel + '</div>').
        parent().
        find(".paginator_prev").
        click(slider_node.loadPrevBatch);
        
    
    if (clip_node.siblings('.paginator_next').size() == 0)
      clip_node.
        after('<div class="paginator_next">' + options.nextLabel + '</div>').
        parent().
        find(".paginator_next").
        click(slider_node.loadNextBatch);

    slider_node.setupIndices();
    slider_node.togglePagination();
    
    
    return slider_node;
  };
})(jQuery);

// =========
// = Popup =
// =========

(function($) {
  Vodspot.Buttons = {
    close: {
      text: "Close",
      click: function(popup) {
        popup.close();
        return false;
      }
    },
    closeOnly: [{
      text: "Close",
      isDefault: true,
      click: function(popup) {
        popup.close();
        return false;
      }
    }],
    standard: function(click) {
      return [
        Vodspot.Buttons.close,
        {text: "Submit", isDefault: true, click: function(popup) {
          if (click) {
            click(popup);
            popup.loading();
            return false;
          }
        }}
      ]
    }
  };

  Vodspot.Popup = function(options) {
    this.init(options);
  };

  $.extend(Vodspot.Popup.prototype, {
    container: null,
    load_img: $('<div style="text-align:center;"><img class="progress" src="/images/hosted/popup/progress.gif"></div>'),
    options: null,
  
    init: function(options) {
      // Close an already existing popup
      if (window.popup) window.popup.close();
      var popup = this;
      window.popup = this;
      this.options = options;
      options.width = options.width || 400;
      options.height = options.height || 300;
    
      var left = ($(window).width() - options.width) / 2 + $(document).scrollLeft();
      var top = ($(window).height() - options.height) / 2 + $(document).scrollTop();
    
      var container = $('<div class="popup" style="display:none;"></div>').css({
        position: 'absolute',
        width: options.width + 'px',
        height: options.height + 'px',
        top: top + 'px',
        left: left + 'px',
        zIndex: '1000'
      });
      
      this.container = container;
    
      if (options.container_params) {
        container.attr(options.container_params);
      }
    
      container.append($('<div class="north"></div>').css({
        position: 'absolute',
        backgroundImage: 'url(/images/hosted/popup/north.png)',
        height: '10px',
        top: '0',
        left: '10px',
        width: (options.width - 20) + 'px'
      }));
      
      container.append($('<div class="south"></div>').css({
          position: 'absolute',
          backgroundImage: 'url(/images/hosted/popup/south.png)',
          height: '10px',
          bottom: '0',
          left: '10px',
          width: (options.width - 20) + 'px'
        }));
        
      container.append($('<div class="east"></div>').css({
        position: 'absolute',
        backgroundImage: 'url(/images/hosted/popup/east.png)',
        width: '10px',
        top: '10px',
        right: '0',
        height: (options.height - 20) + 'px'
      }));
          
      container.append($('<div class="west"></div>').css({
        position: 'absolute',
        backgroundImage: 'url(/images/hosted/popup/west.png)',
        width: '10px',
        top: '10px',
        height: (options.height - 20) + 'px'
      }));
    
      var corner_css = {
        position: 'absolute',
        backgroundImage: 'url(/images/hosted/popup/popup_corners.png)',
        width: '10px',
        height: '10px'
      }
    
      container.append($('<div class="northwest"></div>').css(corner_css).css({
        backgroundPosition: '0 0px',
        top: '0',
        left: '0'
      }));
    
      container.append($('<div class="northeast"></div>').css(corner_css).css({
        backgroundPosition: '0 30px',
        top: '0',
        right: '0'
      }));
    
      container.append($('<div class="southwest"></div>').css(corner_css).css({
        backgroundPosition: '0 10px',
        bottom: '0',
        left: '0'
      }));
    
      container.append($('<div class="southeast"></div>').css(corner_css).css({
        backgroundPosition: '0 20px',
        bottom: '0',
        right: '0'
      }));
    
      container.append($('<div class="header"></div>').css({
        padding: '0 5px',
        position: 'absolute',
        fontWeight: 'bold',
        fontSize: '14px',
        top: '10px',
        left: '10px',
        height: '24px',
        lineHeight: '24px',
        backgroundColor: '#ddd',
        border: '1px solid #000',
        color: '#000',
        width: (options.width - 32) + 'px'
      })
        .text(options.title));
    
      var content = $('<td valign="middle"></td>').append(this.load_img);
    
      container.append(
        $('<div class="content"></div>').css({
            position: 'absolute',
            top: '36px',
            left: '10px',
            backgroundColor: '#fff',
            borderBottom: '1px solid #000',
            borderLeft: '1px solid #000',
            borderRight: '1px solid #000',
            padding: '10px',
            width: (options.width - 42) + 'px',
            height: (options.height - (options.buttons ? 96 : 67)) + 'px',
            'overflow-y': options.scroll ? 'scroll' : 'hidden' })
          .append($('<table style="width:100%;height:100%"></table>')
            .append($('<tr></tr>')
              .append(content)))
      );
    
      if (options.buttons) {
        var footer = $('<div class="footer"></div>').css({
          backgroundColor: '#fff',
          padding: '3px 5px',
          position: 'absolute',
          bottom: '10px',
          left: '10px',
          height: '22px',
          borderBottom: '1px solid #000',
          borderLeft: '1px solid #000',
          borderRight: '1px solid #000',
          width: (options.width - 32) + 'px'
        });
    
        $.each(options.buttons.reverse(), function() {
          var click = this.click;
          var b = $('<a href="#" class="submit_button"></a>').css({
            display: 'block',
            float: 'right',
            padding: '0 7px',
            border: '1px solid #666',
            textDecoration: 'none',
            backgroundColor: '#ddd',
            '-moz-border-radius': '3px',
            '-webkit-border-radius': '3px',
            'border-radius': '3px'
          });
        
          if (this.css) { b.css(this.css); }
          if (this.id)  { b.attr('id', this.id); }
        
          b.text(this.text);
      
          if (click) {
            b.click(function() {
              return click(popup);
            });
          }
        
          if (this.isDefault) {
            $(window).keyup(function(e) {
              var code = (e.keyCode ? e.keyCode : e.which);
              if (code == 13) { // Enter
                b.click();
              }
            });
          }
      
          footer.append(b);
        });
      
        $(window).keyup(function(e) {
          var code = (e.keyCode ? e.keyCode : e.which);
          if (code == 27) { // Escape
            popup.close();
          }
        });
    
        container.append(footer);
      }
    
      $(document.body).append(container);
      container.fadeIn('fast');
    
      var setupContent = function() {
        $('input[type=text]:first, textarea:first', content).focus();
      
        if (options.complete) {
          options.complete(popup);
        }
      }
    
      if (options.url) {
        content.load(options.url, null, setupContent);
      }
    
      if (options.data) {
        content.html(options.data);
        setupContent();
      }
    },
    
    resize: function(height) {
      if (height == this.options.height)
        return;
      
      this.options.height = height;
            
      this.container.css({
        height: height + 'px',
        top: (($(window).height() - height) / 2 + $(document).scrollTop()) + 'px'
      });
      
      this.container.find('.east, .west').css({
        height: (height - 20) + 'px'
      });
      
      this.container.find('.content').css({
        height: (height - (this.options.buttons ? 96 : 67)) + 'px'
      });
    },
  
    loading: function() {
      $('td', this.container).html(this.load_img);
    },
  
    close: function() {
      var popup = this;
    
      this.container.fadeOut('fast', function() {
        popup.closeNow();
      });
    },
  
    closeNow: function() {
      if (this.options.close) {
        this.options.close(this);
      }
    
      this.container.remove();
    }
  });

  Vodspot.DynamicPopup = function(options) {
    this.init(options);
  };

  $.extend(Vodspot.DynamicPopup.prototype, {
    init: function(options) {
      options.width = options.width || 500;
    
      if (options.data) {
        this.showPopup(options, options.data);
      } else {
        this.fromUrl(options);
      }
    },
  
    fromUrl: function(options) {
      var that = this;
    
      var waitingPopup = new Vodspot.Popup({
        width: options.width,
        height: 150,
        title: 'Loading...'
      });
    
      $.post(options.url, options.form_data, function(data) {
        waitingPopup.closeNow();
        that.showPopup(options, data);
      });
    },
  
    showPopup: function(options, data) {
      var div = $('<div style="float:left;display:none;"></div>')
        .css("width", (options.width - 42) + 'px');
    
      $(document.body).append(div);
      div.html(data);
      var height = div.height();
      div.remove();

      var scroll = false;
    
      if (height > 350) {
        height = 350;
        scroll = true;
      }

      options.scroll = scroll;
      options.width = (options.width || 500) + (scroll ? 40 : 0);
      options.height = height + 110;
      options.data = data;
    
      new Vodspot.Popup(options);
    }
  });
})(jQuery);

//==============
//= Google API =
//==============
(function($) {
  Vodspot.googleAPICallbacks = [];
  Vodspot.googleAPILoaded = false;

  Vodspot.loadGoogleAPI = function(key, module, version, callback) {
    Vodspot.googleAPICallbacks.push({callback: callback, module: module, version: version})

    // Make sure it's not already included.
    $.each($('script[src]'), function() {
      if ($(this).attr('src').indexOf('google.com/jsapi') > -1) {
        if (Vodspot.googleAPILoaded) {
          Vodspot.googleAPILoad();
        }
        return
      }
    });

    // This key is good for the vodspot.tv domain and directories.
    key = key || 'ABQIAAAAXgxaaW7S0UwTHdeJYG-7qRTglewquQAhKmzAOg6mj46xhTDnhhQn6V_tUElebh5q7PmEiPT3QZ13Eg';

    $('head').append(
      '<script type="text/javascript" src="http://www.google.com/jsapi?key=' +
      key + '&callback=Vodspot.googleAPILoad"></script>');
  }

  Vodspot.googleAPILoad = function() {
    Vodspot.googleAPILoaded = true;

    $.each(Vodspot.googleAPICallbacks, function() {
      google.load(this.module, this.version, {'callback': this.callback});
    });

    Vodspot.googleAPICallbacks = [];
  }  
})(jQuery);

//===============
//= Feed Reader =
//===============

(function($) {
  $.fn.rssReader = function(options) {
    this.each(function(){
      container = this;
    
      Vodspot.loadGoogleAPI(options.key, "feeds", "1", function() {
        var feedControl = new google.feeds.FeedControl();

        $.each(options.feeds, function() {
          feedControl.addFeed(this.url, this.title);
        });

        feedControl.draw(container);
      });
    });
  };
})(jQuery);

(function($) {
  $(document).ready(function() {
    // Setup global Ajax error handler
    $(document).bind("ajaxError", $.vp.ajaxError);
    $(document).bind("ajaxComplete", $.vp.ajaxComplete);
  }); 
})(jQuery);
