/*
  MAGMA JavaScript
  ------------------------------
  Application JavaScript

*/
function q(a) {$('#q').val(a);}
String.prototype.strip = function() {return this.replace(/^\s+|\s+$/, '');};

function fbs_click(u, t) {window.open('http://www.facebook.com/sharer.php?u='+encodeURIComponent(u)+'&t='+encodeURIComponent(t),'sharer','toolbar=0,status=0,width=626,height=436');return false;}

(function($) {
  $.ajaxForm = {};

  $.fn.ajaxForm = function(opts) {
    var $s = $.extend($.evalJSON($.toJSON($.ajaxForm.defaultSettings)), {});/*(settings && typeof(settings) == 'object' ? settings : {}));*/
    $s.form = this;

    if ($(this).get(0).tagName.toLowerCase() == 'form') {
      $s.opts = $.extend($.ajaxForm.opts, {url : $s.form.attr('action'), type : $s.form.attr('method')}, (opts && typeof(opts) == 'object' ? opts : {}));
      $(this).submit(function() {
        $.ajaxForm.getData($s);
        //alert( $.toJSON($s.opts) );
        try {
          if ($s.opts.GA.cat) gaTrackEvent($s.opts.GA.cat, $s.opts.GA.val, $s.opts.GA.opt_label, $s.opts.GA.opt_val);
          if ($s.opts.GA.page) gaTrackPage($s.opts.url);
        } catch(e) {}
        $.ajax($s.opts);
        return false;
      });
    }
  };

	$.extend($.ajaxForm, {
	  defaultSettings : {},
	  opts : {url : false, type : false, data : false},

	  getData : function($s) {
	    var data = [];
	    $s.form.find('input, textarea, select').each(function() {
	      var f = $(this), tag = f.get(0).tagName.toLowerCase(), name = f.attr('name'), type = f.attr('type');
        if (tag == 'input' || tag == 'textarea') {
          if (type == 'file' || type == 'password' || type == 'image' || type == 'submit' || type == 'button') {
          } else if (type == 'radio' || type == 'checkbox') {
            if (f.get(0).checked) data.push(name+'='+ encodeURIComponent(f.val()) );
          } else {
            data.push(name+'='+ encodeURIComponent(f.val()) );
          }
        } else if (tag == 'select') {
          data.push(f+'='+ encodeURIComponent(f.get(0).options[f.get(0).selectedIndex].value) );          
        }
        $s.opts.data = data.join('&');
	    });
	  }
	});
})(jQuery);



/* TODO : Make this three funcs into a better library. */
$.fn.sTabs = function(obj) {
  if (obj.init) {
    return this.find('dl.tabs dd:eq(0) a').click();
  } else if (obj.tabs) {
    return this.each(function() {
      var tab = this;
      $(obj.tabs+' dl.tabs dd a').each(function() {
        $(this).parent().addClass((this == tab) ? 'current' : '').removeClass((this == tab) ? '' : 'current');
      });

      if (obj.func && typeof(obj.func)== 'function') obj.func();
    });
  }
};

$.fn.menuDrop = function(skipClick) {
  return this.each(function() {
    var gatrack = $(this).attr('rel');
    $(this).hover(function() {}, function() {$(this).removeClass('open');}).append('<div class="arrow abs"></div>');
    $(this).children('.arrow').hover(function() {$(this).parent().addClass('open');}, function() {}).click(function() {var r = $(this).parent(); if (r.hasClass('open')) {r.removeClass('open');} else {r.addClass('open');}});
    if (!skipClick) {$(this).children('.items').children('.item').children("a").click(function() {if (gatrack != '') {parts = gatrack.split(', '); gaTrackEvent(parts[0], parts[1], parts[2], parts[3]);} $(this).menuDropClick();});}
    ($(this).children('.items').children('.selected').size() > 0 ? $(this).children('.items').children('.selected') : $(this).children('.items').children('.item:eq(0)')).hover(function() {$(this).parent().parent().addClass('open');}, function() {}).addClass('selected').addClass('abs');
  });
};

$.fn.menuDropClick = function(skipOpen) {
  if ($(this).parent().hasClass('selected')) {
    var r = $(this).parent().parent().parent();
    if (!skipOpen) {
      if (r.hasClass('open')) {r.removeClass('open');} else {r.addClass('open');}
    }
  } else {
    $(this).parent().parent().children('.item').removeClass('abs').removeClass('selected').children("a").hover(function() {}, function() {});
    $(this).hover(function() {$(this).parent().parent().parent().addClass('open');}, function() {}).parent().addClass('selected').addClass('abs').parent().parent().removeClass('open');
  }
  return false;
};


$.fn.navDrop = function() {
  return this.each(function() {
    var m = this;
    $(this).hover(function () {clearTimeout(m.to); m.to = setTimeout(function() {$(m).addClass('open');}, 200);}, function() {clearTimeout(m.to); m.to = setTimeout(function() {$(m).removeClass('open');}, 200);});
  });
};

$.fn.postClick = function() {
  return this.each(function() {
    var x;
    if (this.onclick != null) {
      x = (this.onclick + '').replace(/^function anonymous\(\)/, '').replace(/^function onclick\(event\)/, '').replace(/^function onclick\(evt\)/, '').replace(/return false\;/, '').replace(/this/, '$(elm)').strip().replace(/^\{/, '').replace(/\}$/, '').strip();
      if (navigator.userAgent.indexOf('Chrome')) x = x.replace(/with \(\$\(elm\)\.ownerDocument \? this\.ownerDocument \: \{\}\) \{/, '').replace(/with \(this\.form \? this\.form \: \{\}\) \{/, '').replace(/with \(this\) \{/, '').replace(/return \(function\(evt\)\{/, '').replace(/\}\)\.call\(this, evt\);/, '').replace(/\}$/, '').strip().replace(/\}$/, '').strip().replace(/\}$/, '').strip().replace(/\(this/, '($(elm)');
    }
    this.postClick = new Function("elm", (x ? x : "void(0)"));
  });
};

$.fn.formFocus = function(l) {
  return this.each(function() {
    $(this).unbind('blur').blur(function() {if (this.value == '' || this.value == l) {this.value = l; $(this).addClass("empty");}});
    $(this).unbind('focus').focus(function() {if (this.value == l) {this.value = ''; $(this).removeClass("empty");}});
    if (this.value == '' || this.value == l || this.value == this.l) {this.value = l; $(this).addClass("empty");}
    this.l = l;
  });
};

$.fn.getVideoId = function() {
  var c = this.attr('class').split(" ");
  for(var i=0; i<c.length; i++) if (c[i].match(/video\_/ig)) return parseInt(c[i].replace(/video\_/ig, ''));
  return false;
};

$.fn.vbuttons = function(prefix) {
  if (!prefix || prefix == '') prefix = '.vbutton';
  return this.each(function() {
    var vid = $(this).getVideoId();
    if (vid) {
      if (Session.LoggedIn) {
/*        if (Session.Queue) {
          if (jQuery.inArray(vid, Session.Queue) >= 0) {
            $(this).find(prefix+'.queue').addClass('video_'+vid).addClass('current').attr('title', 'Remove from Queue').unbind('click').click(Channels.Queue.Current);
          } else {
            $(this).find(prefix+'.queue').addClass('video_'+vid).attr('title', 'Add to Queue').unbind('click').click(Channels.Queue.Add);
          }
        }
*/
        if (Session.LikesVideo(vid)) {
          $(prefix+'.fave', this).addClass('video_'+vid).addClass('current').attr('title', 'Unlike this Video').unbind('click').click(Channels.Channel.Unlike);
        } else {
          $(prefix+'.fave', this).addClass('video_'+vid).attr('title', 'Like this Video!').unbind('click').click(Channels.Channel.Like);
        }

        if (Session.InChannel(vid)) {
          var cb = $(prefix+'.channels', this);
          /* $(prefix+'.fave', this).hide(); */
          if (cb.length > 0) {
            cb.addClass('video_'+vid).addClass('edit').attr('title', 'Edit Video').unbind('click').click(Channels.Channel.Edit);
          } else {
            $('.vbuttons', this).prepend('<dd><a class="'+ prefix.replace(/\./, '') +' channels edit" href="'+ Channels.Route('add', 'user', vid) +'" title="Add to Channel"></a></dd>').find(prefix+'.channels').addClass('video_'+vid).addClass('current').attr('title', 'Edit Video').unbind('click').click(Channels.Channel.Edit);
          }
        } else {
          $(prefix+'.channels', this).addClass('video_'+vid).attr('title', 'Add to Channel').unbind('click').click(Channels.Channel.Add);
        }

        if (Session.Admin) Channels.Admin(this, vid);
      } else {
        /* $(prefix+'.queue', this).addClass('video_'+vid).unbind('click').click(Channels.Queue.New); */
        $(prefix+'.channels', this).addClass('video_'+vid).unbind('click').click(Channels.Channel.New);
      }
    }
  });
};

// Google Analytics Event Tracking shortcuts
// Track a full page hit
function gaTrackPage(url) {
  if (!url || url == '') return; 
  try {pageTracker._trackPageview(parse_path(url));} catch (err) {}
}

// Track a single on-click event
// e.g. %a{:href => jobs_path, :onclick => "gaTrackEvent('Users', 'Feedback', 'Footer Link');"}
function gaTrackEvent(cat, action, opt_label, opt_val) {
  if (!cat || cat == '') return; 
  try { if (!action || action == '') action = '-n/a-'; pageTracker._trackEvent(cat, action, opt_label, opt_val); } catch(err) {}
}



var Session = {
  LoggedIn:false,Queue:[],Likes:{},Channels:{},ChannelVideos:{},Admin:false,ChannelAdmin:false,
  InChannel : function(vid) {return (vid > 0 && this.ChannelVideos[vid] && (typeof(this.ChannelVideos[vid]) == 'object' || (typeof(this.ChannelVideos[vid]) == 'string' && this.ChannelVideos[vid] != '')));},
  LikesVideo : function(vid) {return (vid > 0 && this.Likes.Videos && this.Likes.Videos.indexOf(vid) >= 0);},
  GetChannel : function(kind, i) {if (!i) i = 0; return (this.Channels[kind] ? (typeof(this.Channels[kind]) == 'object' ? this.Channels[kind][i] : this.Channels[kind]) : false);},
  AddChannelVideo : function(vid, cid, cvid) {if (!(/\d+/.test(cid))) cid = this.GetChannel(cid); if (/\d+/.test(cid)) {if (!this.ChannelVideos[vid]) this.ChannelVideos[vid] = {}; this.ChannelVideos[vid][cid] = cvid; return true;} else {return false;}},
  RemoveChannelVideo : function(vid, cid) {if (!(/\d+/.test(cid))) cid = this.GetChannel(cid); if (/\d+/.test(cid) && this.ChannelVideos[vid] && this.ChannelVideos[vid][cid]) {delete this.ChannelVideos[vid][cid]; if (this.ChannelVideos[vid] && !(/[A-Z0-9]+/i.test($.toJSON(this.ChannelVideos[vid])))) delete this.ChannelVideos[vid]; return true;} return false;}
};

var Channels = {
  Values : {timeout : false},
  Route : function(action, cid, vid, ext) {return '/channel_videos/'+cid+'/'+action+'/'+vid+(ext && ext != '' ? '.'+ext : '');},
  /*
  Queue : {
    Counts : function() {
      $('#s_nav_queue span span, #default_user .queue span').html(Session.Queue.length > 0 ? Session.Queue.length : '0');
      $('#nav_queue').attr('title', 'Queue ('+Session.Queue.length+' videos)');
    },
    Current : function() {
     if (Session.Queue) {
        var r = this;
        $.ajax({type: "GET", url: r.href+'/remove', success: function(html){
          var vid = $(r).getVideoId();
          if (vid && jQuery.inArray(vid, Session.Queue) > 0) Session.Queue.splice(jQuery.inArray(vid, Session.Queue), 1);
          $(vid ? '.queue.video_'+vid : r).removeClass('current').attr('title', 'Add to Queue').unbind('click').click(Channels.Queue.Add);
          Channels.Queue.Counts();
        }, error: function(){alert('Sorry, this video could not be removed from your queue.');}});
      }
      return false;
    },
    Add : function() {
      if (Session.Queue) {
        var r = this;
        $.ajax({type: "GET", url: r.href.replace(/remove/ig, 'add'), success: function(html){
          var vid = $(r).getVideoId();
          if (vid && jQuery.inArray(vid, Session.Queue) < 0) Session.Queue.push(vid);
          $(vid ? '.queue.video_'+vid : r).addClass('current').attr('title', 'Remove from Queue').unbind('click').click(Channels.Queue.Current);
          Channels.Queue.Counts();
        }, error: function(){alert('Sorry, this video could not be added to your queue.');}});
      }
      return false;
    },
    New : function() {if (Session.Queue) $.facebox({ajax:'/signup'}); return false;}
  },
  */
  
  Channel : {
    Counts : function() {$('#default_user .channel span').html(Session.ChannelVideos.length > 0 ? Session.ChannelVideos.length : '0');},
    Remove : function(r, fbx, redirect) {
      if (!confirm('Are you sure you want to remove this video from your channel?')) return false;
      var r = (r || this), vid = $(r).getVideoId(), cid = Session.ChannelAdmin || 'user';
      gaTrackEvent('Channel Video', 'Remove', 'Video '+vid);
      $.ajax({type: "DELETE", url: Channels.Route('remove', cid, vid), success: function(html){
        $(document).unbind('beforeClose.facebox');
        $(window).unbind('unload');
        Session.RemoveChannelVideo(vid, 'user');
        if (redirect) {
          location.href = redirect;
        } else {
          if (fbx == 'bookmarklet') {window.opener.focus(); window.close();}
          if (fbx) $.facebox.close();
          if (Session.ChannelAdmin) {
            opts = (!Session.ChannelAdmin && $(r).parents(".video.box")) ? {width: "toggle", paddingTop: 0, paddingBottom: 0} : {height: "toggle", paddingTop: 0, paddingBottom: 0};
            (Session.ChannelAdmin ? $(vid ? '.video.video_'+vid : r) : $(vid ? '.channels.video_'+vid : r).parent()).animate(opts, (Session.ChannelAdmin ? 500 : 250), false, function() {$(this).remove();});
            /* TODO : detect if parent has no more children (in list mode) or parent parent (in grid mode), and show prompt. */
          } else {
            $('.channels.video_'+vid).removeClass('edit').attr('title', 'Add to Channel').unbind('click').click(Channels.Channel.Add);
            /* $('.video_'+vid+' .fave').animate({'height':'show'}, 250); */
          }
          Channels.Channel.Counts();
        }
      }, error: function(){alert('Sorry, this video could not be removed from your channel.');}});
      return false;
    },
    Add : function(etc) {
      var r = this, vid = $(r).getVideoId(), cid = Session.GetChannel('user');
      gaTrackEvent('Channel Video', 'Add', 'Video '+vid);
      $.ajax({type:'PUT', url:Channels.Route('add', cid, vid)+(etc && typeof(etc) == 'string' && etc != '' ? '?'+etc : ''), data:{}, success: function(html){
        $('.channels.video_'+vid).addClass('edit').attr('title', 'Edit Video').unbind('click').click(Channels.Channel.Edit);
        Channels.Channel.Counts();
        $.facebox(html, 'cv_fbx_form');
      }, error: function(){alert('Sorry, this video could not be added to your channel.');}});
      return false;
    },
    Edit : function() {
      var r = this, vid = $(r).getVideoId(), cid = Session.GetChannel('user'), etc = '';
      $.ajax({type:'GET', url:Channels.Route('edit', cid, vid), success: function(html){Channels.Channel.Update(vid, html);}, error: function(){alert('Sorry, this video could not be edited within your channel.');}});
      return false;
    },
    Update : function(vid, html, first) {
      /* $('.video_'+vid+' .fave').animate({'height':'hide'}, 250); */
      var cid = Session.GetChannel('user');
      if (Channels.Values.timeout) clearTimeout(Channels.Values.timeout);
      $.facebox('<div id="channel_video_ajax_edit"></div>', 'cv_fbx_form');
      $('#channel_video_ajax_edit').html(html).find('a[rel=close]').click(function() {$('#channel_video_ajax_edit').remove(); return false;});
    },
    New : function() {$.facebox({ajax:'/signup'}); return false;},
    Like : function() {
      var r = this, vid = $(r).getVideoId();
      gaTrackEvent('Liking', 'Like', 'Video '+vid);
      $.ajax({url: $(this).attr('href'), type:'GET', success : function(request) {
        $('.video_'+vid+' .fave').addClass('current').attr('title', 'Unlike this Video').unbind('click').click(Channels.Channel.Unlike);
        $('#video_quickstats .comments .votes span:eq(0), #video_quickstats .votes .today span:eq(0)').valChange({after:{element:'#video_quickstats .votes', highlight:true}});
      }, error : function() {alert('This video could not be liked.');} });
      return false;
    },
    Unlike : function() {
      var r = this, vid = $(r).getVideoId();
      gaTrackEvent('Liking', 'Unlike', 'Video '+vid);
      $.ajax({url: $(this).attr('href').replace(/\/create/i, ''), type:'GET', success : function(request) {
        $('.video_'+vid+' .fave').removeClass('current').attr('title', 'Like this Video!').unbind('click').click(Channels.Channel.Like);
        $('#video_quickstats .comments .votes span:eq(0), #video_quickstats .votes .today span:eq(0)').valChange({incr:-1,min:0,after:{element:'#video_quickstats .votes', highlight:true}});
      }, error : function() {alert('This video could not be unliked.');} });
      return false;
    }
  },
  Admin : function() {}
};

function parse_domain(str) {return str.replace(/^(http|https)(\:\/\/)([A-Z0-9\@\:\.\-\_]*)(.*)/i, '$1$2$3');}
function parse_path(str) {return str.replace(/^(http|https)(\:\/\/)([A-Z0-9\@\:\.\-\_]*)(.*)/i, '$4');}


var Video = {
  Values : {StatsUpdated : false},
  UpdateStats : function(url) {
    if (this.Values.StatsUpdated) return;
    $.ajax({url:url, type:'PUT',
      success : function(request) {
        $('#video_mast').before('<div id=\"video_stats_msg\" class=\"flash_notice flash_message hide\">'+ request +'</div>');
        $('#video_stats_msg').removeClass('hide').hide().animate({'height':'show'}, 350);
      }, error : function() {alert('Sorry, but an error occurred when trying to update the video stats.');}
    });
  }
};

/* Click to play */
$.fn.click2play = function() {
  return this.attr("title", "Click to Watch").append('<img src="/images/blank.png" title="Click to Watch" alt="" border="0" class="arrow" />').click(function() {
    var vid = $(this).getVideoId(), replace = '.video.video_' + vid, vidbox = $(this).parents('.video'), href = location.href;

    /* To work with jQuery.anchoring, get the url at the end of the page */
    if (/\#\//.test(href)) {
      href = href.replace(/^(.*)(#)(.*)$/, parse_domain(href)+'$3');
    } else if (/\#/.test(href)) {
      href = href.replace(/^(.*)(#)(.*)$/, '$1$3');
    }

    /* Append all parameter values to the end of the string */
    href = (href.match(/\?/) ? href.replace(/([A-Z0-9\:\/\\\-\_\.]*)(\?)(.*)$/i, '$1/play/'+vid+'$2$3') : href+'/play/'+vid);
    /* Strip out page number (not really necessary) and ? if was only parameter */
    href = href.replace(/(page=)(\d+)/i, '').replace(/(\?)$/, '');

    gaTrackEvent('Video', 'Click2Play', 'Video '+vid);
    $.ajax({type:"GET", url:href, success: function(request){vidbox.replaceWith(request);}, error: function(request){alert('Sorry, but an error occured when trying to play this video.');}});
    return false;
  });
};


/* Keybindings (via jquery.hotkeys) -- 
 * plans to add prev/next, field selection, quick-share/add/etc. 
*/

/* Konami Code */
/* modified from http://static.jquery.com/files/rocker/scripts/custom.js (thx guise!) */
var kc={l:function(e){kc.k.push(e.keyCode);if (kc.k.toString().indexOf(kc.c) >= 0){kc.k=[];kc.d();}},d:function() {alert('A Winner Is You!');},c:"38,38,40,40,37,39,37,39,66,65",k:[]};
$(window).keydown(kc.l);

/* F2 (keycode 113) => show console */
/* TODO DRY console animation */
$(window).bind('keydown', function(event){
  if(event.keyCode != 113) return;
  $('#admin_console #admin_console_content').animate({'height':'toggle'}, 200, function() {$('a#admin_console_button').attr('class', ($('a#admin_console_button').hasClass('open') ? 'closed' : 'open'));});
});

/* Channel sorting */
var ChannelSort = {
  Values : {AuthToken:'', Url:'', Container:'ul.videos', Items:'.video'},
  Init : function(vals, opts) {
    this.Values = $.extend(this.Values, vals);
    this.Opts = $.extend(this.DefaultOpts, opts);
    $(this.Values.Container).sortable(this.Opts);
  },
  UpdateIndex : function(data) {},
  DefaultOpts : {
    axis:'y', dropOnEmpty:false, update:function() {var data = $(this).sortable('serialize', {key: 'video', attribute:'class', expression:/video_(\d+)/}); ChannelSort.UpdateIndex(data.replace(/[a-z\[\]\=]+/g, '').split("&")); $.ajax({url:ChannelSort.Values.Url, data:data + '&authenticity_token=' + encodeURIComponent(ChannelSort.Values.AuthToken), dataType:'script', type:'post'});}
  }
};

/* move element to a high z-index */
$.fn.zindex = function(obj) {
  var settings = {zindex:2000};
  if (typeof(obj) == 'object') settings = $.extend(settings, obj);
  return this.each(function(i) {$(this).css({'z-index': (settings.zindex-i)});});
};


$.fn.valChange = function(attr) {
  var vc = $.extend({incr:1, min:false, max:false, after:false}, attr), ef = false;
  if (attr && attr.after && typeof(attr.after) == 'object') ef = $.extend(true, {element:false, highlight:false, beforeCss:false, css:false, duration:1000, after:false}, attr.after);
  if (!vc.incr || vc.incr == '') vc.incr = 1;

  var self = this.each(function(i) {
    var v = parseInt($(this).html())+vc.incr;
    if (vc.min !== false && vc.max !== false && vc.min > vc.max) {vc.max = false; vc.min = false;}
    if (vc.min !== false && vc.min > v) v = vc.min;
    if (vc.max !== false && vc.max < v) v = vc.max;
    $(this).html(v+'');
  });

  if (typeof(ef) == 'object' && ef.element) {
    if (ef.highlight) {
      $(ef.element).css({'backgroundColor':'#fffabc'}).animate({'backgroundColor':'#ffffff'}, 750, ef.after);
    } else {
      if (ef.beforeCss) $(ef.element).css(ef.beforeCss);
      $(ef.element).animate(ef.css, ef.duration, ef.after);
    }
  }

  return self;
};

function commify(num) {var str_num = (num+'').split('').reverse().join(''), str = ''; for (var i=0; i<str_num.length; i+=3) {if (str != '') str += ','; if (str_num[i]) str += str_num[i]; if (str_num[i+1]) str += str_num[i+1]; if (str_num[i+2]) str += str_num[i+2];} return str.split('').reverse().join('');}


/*
 * jQuery JSON Plugin
 * version: 1.0 (2008-04-17)
 */
(function($) {   
  function toIntegersAtLease(n) {return n < 10 ? '0' + n : n;}
  Date.prototype.toJSON = function(date) {return this.getUTCFullYear()   + '-' + toIntegersAtLease(this.getUTCMonth()) + '-' + toIntegersAtLease(this.getUTCDate());};
  var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
  $.quoteString = function(string) {if (escapeable.test(string)) {return '"' + string.replace(escapeable, function (a) {var c = meta[a]; if (typeof c === 'string') return c; c = a.charCodeAt(); return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);}) + '"';} return '"' + string + '"';};
  $.toJSON = function(o, compact) {var type = typeof(o); if (type == "undefined") {return "undefined";} else if (type == "number" || type == "boolean") {return o + "";} else if (o === null) {return "null";} if (type == "string") return $.quoteString(o); if (type == "object" && typeof o.toJSON == "function") return o.toJSON(compact); if (type != "function" && typeof(o.length) == "number") {var ret = []; for (var i = 0; i < o.length; i++) ret.push( $.toJSON(o[i], compact) ); return "[" + ret.join(compact ? "," : ", ") + "]";} /*if (type == "function") throw new TypeError("Unable to convert object of type 'function' to json.");*/ var ret = []; for (var k in o) {var name; type = typeof(k); if (type == "number") {name = '"' + k + '"';} else if (type == "string") {name = $.quoteString(k);} else {continue;} var val = $.toJSON(o[k], compact); if (typeof(val) != "string") continue; ret.push(name + (compact ? ":" : ": ") + val);} return "{" + ret.join(", ") + "}";};
  $.compactJSON = function(o) {return $.toJSON(o, true);};
  $.evalJSON = function(src) {return eval("(" + src + ")");};
  $.secureEvalJSON = function(src) {var filtered = src.replace(/\\["\\\/bfnrtu]/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''); if (/^[\],:{}\s]*$/.test(filtered)) {return eval("(" + src + ")");} else {throw new SyntaxError("Error parsing JSON, source is not valid.");}};
})(jQuery);
if(!this.JSON){JSON=function(){function f(n){return n<10?'0'+n:n;} Date.prototype.toJSON=function(key){return this.getUTCFullYear()+'-'+ f(this.getUTCMonth()+1)+'-'+ f(this.getUTCDate())+'T'+ f(this.getUTCHours())+':'+ f(this.getUTCMinutes())+':'+ f(this.getUTCSeconds())+'Z';};var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapeable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapeable.lastIndex=0;return escapeable.test(string)?'"'+string.replace(escapeable,function(a){var c=meta[a];if(typeof c==='string'){return c;} return'\\u'+('0000'+ (+(a.charCodeAt(0))).toString(16)).slice(-4);})+'"':'"'+string+'"';} function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);} if(typeof rep==='function'){value=rep.call(holder,key,value);} switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';} gap+=indent;partial=[];if(typeof value.length==='number'&&!(value.propertyIsEnumerable('length'))){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';} v=partial.length===0?'[]':gap?'[\n'+gap+ partial.join(',\n'+gap)+'\n'+ mind+']':'['+partial.join(',')+']';gap=mind;return v;} if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value,rep);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value,rep);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}} v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+ mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}} return{stringify:function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;} rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');} return str('',{'':value});},parse:function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}} return reviver.call(holder,key,value);} cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+('0000'+(+(a.charCodeAt(0))).toString(16)).slice(-4);});} if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;} throw new SyntaxError('JSON.parse');}};}();}



/* find out where the user's been lately to display appropriate Share sites */
/* CURRENTLY NOT IN USE */
(function($) {
  $.sniffVisited = function() {
    return false; /* Not needed, for now... */
    if (!$.sniffVisited.init) {
      $.sniffVisited.domain = window.location.href.replace(/^([a-z]*)(:\/\/)([a-z0-9\-\_\.\:\@]*)(.*)$/i, '$1$2$3');
      if ($('style#style_'+ $.sniffVisited.id).size() < 1) $('body').append('<style id="style_'+ $.sniffVisited.id +'" type="text/css">#links_'+ $.sniffVisited.id +' {display: none;} body a:visited {counter-increment: '+ $.sniffVisited.match +';}</style>');
      if ($('div#links_'+ $.sniffVisited.id).size() < 1) $('body').append('<div id="links_'+ $.sniffVisited.id +'"></div>');
      jQuery($.sniffVisited.against).each($.sniffVisited.test);
    }
    $('a').filter($.sniffVisited.filter).each($.sniffVisited.add);
 
    /* Sniff internal links... */
    if ($.sniffVisited.history.local.length > 0) alert("Internal pages:\n\n"+ jQuery.unique($.sniffVisited.history.local).join("\n"));
    /* Sniff external links... */
    if ($.sniffVisited.history.external.length > 0) alert("External pages:\n\n"+ jQuery.unique($.sniffVisited.history.external).join("\n"));
  };
  $.extend($.sniffVisited, {
    init : false,
    domain : false,
    id : 'jquery_sniffVisited',
    match : 'visited',
    against : ['facebook.com', 'twitter.com', 'youtube.com', 'vimeo.com', 'tumblr.com'],
    history : {local : [], external : []},
    test : function(i) {$('#links_'+ $.sniffVisited.id).append('<a href="http://www.'+ this +'/" /><a href="http://'+ this +'/" /><a href="https://www.'+ this +'/" /><a href="https://'+ this +'/" />');},      
    add : function() {(this.href.indexOf($.sniffVisited.domain) >= 0 ? $.sniffVisited.history.local : $.sniffVisited.history.external).push(this.href);},
    filter : function() {return(/visited/i.test($(this).css('counter-increment')));}
  });
})(jQuery);



/* Nice Tooltips */
(function($) {
  $.ttHelp = function(html, opts) {};

  $.extend($.ttHelp, {
    Values : {Open : false, Timeout:false},
    Open : function(html, opts) {
      var tt_o = false, tt_x = 0, tt_y = 0, timeout = 0, klass = (opts.klass && opts.klass != '' ? opts.klass : ''), css = {}, ss_o = false, ss_w = 0, ss_h = 0 ;

      $(window).trigger('ttHelp.beforeOpen');

      if (opts.element && opts.element != '') {
        tt_o = $(opts.element).offset(); tt_x = tt_o.left; tt_y = tt_o.top;
      } else {
        $(window).mousemove(function(e){tt_x = e.pageX; tt_y=e.pageY});
      }

      if (opts.offset && opts.offset.length == 2) {tt_x = tt_x+opts.offset[0]; tt_y = tt_y+opts.offset[1];}
      if (opts.timeout && opts.timeout > 0) timeout = opts.timeout;
      if (opts.element && opts.element != '') {
        if (opts.right) tt_x += $(opts.element).width();
        if (opts.bottom) tt_y += $(opts.element).height();
      }
      
      this.Close();
      this.Values.TimeoutOpen = setTimeout(function() {
        if ($('#tthelp').size() > 0) {
          $('#tthelp_body').html('');
        } else {
          $('body').append('<div id="tthelp" class="'+ klass +'"></div>');
        }
        css = $.extend({}, opts.css, {'opacity':'0', 'top':tt_y, 'left':tt_x});
        $('#tthelp').hover(function() {clearTimeout($.ttHelp.Values.TimeoutClose);}, function() {$.ttHelp.Close();}).css(css).html('<div id="tthelp_body">'+html+'</div>');

        /* Check if overlapping page */
        ss_o = $('#tthelp').offset(); ss_w = $('#tthelp').width(); ss_h = $('#tthelp').height();
        if ($('body').width() < (ss_o.left + ss_w)) $('#tthelp').css({left: ($('body').width()-ss_w-6)});
        if ($('body').height() < (ss_o.top + ss_h)) $('#tthelp').css({top: ($('body').height()-ss_h-6)}); 

        $('#tthelp').animate({'opacity':'1'}, 250, function() {$.ttHelp.Values.Open = true; $(window).trigger('ttHelp.afterOpen');});
      }, timeout);
    },

    Close : function(animate) {
      clearTimeout(this.Values.TimeoutOpen);
      this.Values.TimeoutClose = setTimeout(function() {
        if ($.ttHelp.Values.Open) {
          $(window).trigger('ttHelp.beforeClose');
          if (animate) {
            $('#tthelp').animate({'opacity':'0'}, 250, function() {$(this).remove(); $.ttHelp.Values.Open = false; $(window).trigger('ttHelp.afterClose');});
          } else {
            $('#tthelp').remove(); $.ttHelp.Values.Open = false; $(window).trigger('ttHelp.afterClose');
          }
        }
      }, 25);
    }
  });
})(jQuery);



/*document.cookie = '_tzinfo=; expires='+ new Date(new Date().getTime() - 1000000000);*/
/* Convert over to jquery cookies plugin */
var cs = document.cookie.split('; '), i, v, found; for (i=0; i<cs.length; i++) {v = cs[i].split('='); if (v[0] == '_tzinfo' && v[1] && v[1] != '') found = true;}
if (!found) {var c = new Date(), o = c.getTimezoneOffset()*-60, n = new Date(c.getTime()+(86400000)); document.cookie = '_tzinfo='+o+'; expires='+n+';';}


/* Cookie plugin - Copyright (c) 2006 Klaus Hartl (stilbuero.de). Dual licensed under the MIT and GPL licenses: http://www.opensource.org/licenses/mit-license.php  http://www.gnu.org/licenses/gpl.html */
$.cookie = function(name, value, options) {
  if (typeof(value) != 'undefined') {
    options = options || {};
    if (value === null) {
      value = '';
      options.expires = -1;
    }
    var expires = '';
    if (options.expires && (typeof(options.expires) == 'number' || options.expires.toUTCString)) {
      var date;
      if (typeof(options.expires) == 'number') {
        date = new Date();
        date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
      } else {
        date = options.expires;
      }
      expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
    }
    var path = options.path ? '; path=' + (options.path) : '';
    var domain = options.domain ? '; domain=' + (options.domain) : '';
    var secure = options.secure ? '; secure' : '';
    document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
  } else {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
      var cookies = document.cookie.split(';');
      for (var i = 0; i < cookies.length; i++) {
        var cookie = jQuery.trim(cookies[i]);
        if (cookie.substring(0, name.length + 1) == (name + '=')) {
          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
          break;
        }
      }
    }
    return cookieValue;
  }
};

/* flag/report video bind */
function flagVideo() {
  $.ajax({url:this.href, type:'get', success:function(request) {$.facebox(request, '', {width: 250});}, error:function() {alert('Sorry, but an error occured when trying to flag this video. Please try again.');} });
  return false;
}


/* Comments-related */
$(window).bind('comments.load', function(e, elm, url) {
  if (!url || url == '') return false;
  $(elm).parent().contents('a').removeClass('selected');
  $(elm).addClass('selected');
  $('#comments_add').animate({'height':'hide','opacity':'0'}, 250, function() {$(this).remove();});
  $('#comments.comments_area').animate({'height':'50','opacity':'0'}, 250, function() {$(this).html('').addClass('loading_simple').animate({'opacity':'100'}, 250);});

  /*gaTrackEvent('Comments', 'Switching Views', url);*/
  $.ajax({url:url, type:'GET',
    success : function(request) {
      $('#comments.comments_area').before(request).remove();
      $('#comments_add').hide().animate({'height':'show'}, 250);
      $('#comments.comments_area').hide().animate({'height':'show'}, 500);
      $('#comments_count').html($('#comments.comments_area .comment').size() > 0 ? $('#comments.comments_area .comment').size() : '0');
    },
    error : function() {alert('Sorry, but the comments could not be loaded at this time.');}
  });
});

$(window).bind('add_comment.ajax', function() {
  $('form#new_comment').submit(function() {
    var form = $(this), comment = form.find('#comment_body'), button = form.find('input[type=submit]');
    if (comment.val() == '') return false;
    var url = form.attr('action'), method = form.attr('method'), opts = {url:url,type:method,data:'',success:false,error:false};
    form.find('input,textarea').each(function() {
      if ($(this).attr('type') == 'submit') return true;
      opts.data += (opts.data != '' ? '&' : '') + $(this).attr('name') +'='+ encodeURIComponent($(this).val());
    });
    comment.addClass('disabled').attr('disabled', 'disabled');
    button.addClass('disabled').attr('disabled', 'disabled');

    $(window).bind('comments_return.ajax', function(e, success) {
      form.find('#comment_body_replace').remove();
      if (success) {
        comment.val('');
        if (form.find('.flash_message').size() > 0) form.find('.flash_message').remove();
      }
      comment.removeClass('disabled').removeAttr('disabled');
      button.removeClass('disabled').removeAttr('disabled');
    });

    opts.success = function(request) {
      $(window).trigger('comments_return.ajax', [true]);
      $('#comments.comments_area').find('p.suggest').animate({'paddingTop':0,'paddingBottom':0,'height':'hide'}, 250, function() {$(this).remove();});
      $('#comments.comments_area').append(request).find('.comment:last').hide().css({backgroundColor:'#fffabc'}).animate({'height':'show'}, 500, function() {$(this).animate({'backgroundColor':'#ffffff'}, 750);});
      $(window).trigger('comments.ready');
      $('#comments_count, #video_quickstats .comments .total span, #video_quickstats .comments .today span:eq(0)').valChange({after:{element:'#video_quickstats .comments', highlight:true}});
    };
    opts.error = function(request) {
      $(window).trigger('comments_return.ajax');
      if (form.find('.flash_message').size() > 0) {
        form.find('.flash_message').fadeOut(250, function() {$(this).html(request.responseText).fadeIn(250);});
      } else if (request.responseText != '') {
        comment.before('<div class="flash_message flash_error hide"></div>');
        form.find('.flash_message').html(request.responseText).hide().removeClass('hide').animate({'height':'show','opacity':'show'}, 250);
      }
    };
    gaTrackEvent('Comments', 'Add', url);
    $.ajax(opts);
    return false;
  });
});
$(window).bind('comments.ready', function() {
  $('.loctime', '.comments_area').locTime();
  if (Session.Admin || Session.UserId) {
    $('#comments.comments_area .comment'+(Session.Admin ? '' : '.user_'+ Session.UserId)).each(function() {
      if ($(this).contents('.delete').size() < 1) {
        $(this).prepend('<a href="#" class="delete abs">X</a>').find('a.delete').click(function() {
          if (!confirm('Are you sure you want to delete this comment?')) return false;
          var box = $(this), id = box.parents('.comment').attr('id').replace(/^(.?)(comment_)(\d+)(.?)$/, '$3'), token = $('input[name=authenticity_token]:first').val();
          if (token == '') return false;
          gaTrackEvent('Comments', 'Delete', '/comments?id='+id);
          $.ajax({type: 'DELETE', url: '/comments', data:'id='+id+ '&authenticity_token=' + encodeURIComponent(token),
            success: function(html) {
              $('#comments_count, #video_quickstats .comments .total span, #video_quickstats .comments .today span:eq(0)').valChange({incr:-1, min:0, after:{element:'#video_quickstats .comments', highlight:true}});
              box.parent().animate({'height':'hide'}, 250, function() {$(this).remove();});
            },
            error : function(response) {alert('Sorry, but an error occured while trying to delete this video.');}
          });
          return false;
        });
      }
    });
  }
});



$(window).bind('bookmarklet.load', function() {
  $('#videos_strip .video.item').each(function() {
    var self = $(this), url = self.attr('rel'), i = self.attr('id').replace(/^(.*)(\d+)$/, '$2'), video = $('#videos_forms #video_'+i), title = $('input[@name="video[cv_title]"]', video), desc = $('textarea[@name="video[cv_description]"]', video), form = video.contents('form');
    if (form.size() > 0) {
      video.addClass('loading').find('form').hide();
      if (!self.hasClass('selected')) video.hide();
      $.ajax({url:'/info.json?url='+encodeURIComponent(url), timeout: 5000, type:'GET', 
        success : function(data){
          full_data = $.evalJSON(data);
          data = full_data[0]; 
          title.val(data.title); 
          desc.val(data.description); 
          video.removeClass('loading').find('form').show();
        }, error : function() {
          desc.val(''); 
          video.removeClass('loading').find('form').show();
        }});
    }
  });
});

/* Main */
$(document).ready(function() {
  $('a.fbx.ajax').click(function() {$.facebox({ajax:this.href}); return false;});
  $('#q').formFocus('Search');
  $('#search_box dl.selector:eq(0)').each(function() {
    var s = $(this), q = $('#search_box #q'), which = $.cookie('search_type');
    q.addClass('smart');
    s.css({'display':'inline-block'}).hover(function() {clearTimeout(s.to); s.to = setTimeout(function() {s.addClass('hover');}, 200);}, function() {clearTimeout(s.to); s.to = setTimeout(function() {s.removeClass('hover');}, 200);});
    $('dd a', s).click(function() {
      var type = $(this).parent().attr('class');
      $('#search_box form').attr('action', this.href);
      q.formFocus($(this).html());
      /*q.attr('class', (q.hasClass('empty') ? 'empty' : '')).addClass(type);*/
      s.attr('class', 'selector' + (s.hasClass('hover') ? ' hover' : '')).addClass(type);
      $('dd a', s).removeClass('selected');
      $(this).addClass('selected');
      $.cookie('search_type', type);
      gaTrackEvent('UX Testing', 'Search Toggle', type);
      return false;
    });
    s.find('dd'+ (which && which != '' ? '.'+which : '') +' a:eq(0)').click();
  });

  $(window).bind('channel.load', function(e, context, vid) {
    vid = (vid > 0 ? '.video.video_'+vid : '.video');

    if (typeof($.locTime) == 'function') $('.loctime', context).locTime();
    $(vid+', #video_icons', context).vbuttons();
    $(vid, context).hover(function() {$(this).addClass('hover');}, function() {$(this).removeClass('hover');});
    $(vid+'.box', context).click(function(e) {if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey) return true; location.href = $(this).find('a:first').attr('href'); return false;});
    $(vid+' a.flag', context).click(flagVideo);
    $(vid+' a.click2play', context).click2play();
  }).trigger('channel.load', false);

  /* $(".video img").lazyload(); */

  $('.menu').menuDrop();
  $('.drop').navDrop();
  $('.drop, .drop .cols, .menu, .menu .items, .menu .items .item, .menu .items .arrow').zindex();
  $('.page_announcement a.close').click(function() {
    var self = this;
    gaTrackEvent('Announcements', 'Dismiss', self.href);
    $.ajax({type:'GET', url:self.href, success:function() {
      var r = $(self).parent();
      if (r.parent().children().size() == 1) r = r.parent();
      r.animate({'height':'toggle','paddingTop':'0','paddingBottom':'0','marginTop':'0','marginBottom':'0', 'borderTop':'0', 'borderBottom':'0'}, 250, function() {$(this).remove();});}, error:function(response) {alert('Sorry, but this announcement could not be dismissed. Please try again.');}
    });
    return false;
  });

  $(window).bind('js_tt.load', function(e, n, opts) {
    $(n && typeof(n) == 'string' && n != '' ? n : '.js_tt').hover(
      function() {
        $(this).contents().find('*[title]').removeAttr('title');
        var o = $.extend({}, {element:this, offset:[190,-10], timeout: 500}, (opts && typeof(opts) == 'object' ? opts : {}) );
        $.ttHelp.Open($(this).contents('.js_tt_about').html(), o);
      },
      function() {$.ttHelp.Close();}
    );
  }).trigger('js_tt.load');//.trigger('js_tt.load', ['.js_tt_video', {klass: 'video', right: true, offset: [-20,25]}] );

  $(window).bind('e_obf.load', function(n) {
  	$((n && typeof(n) == 'string' && n != '' ? n+' ' : '') + '.e_obf').each(function() {
  		var c = $(this).text().replace(/&nbsp;|\s/g, '').replace(/\(at\)/ig, '@').replace(/\(dot\)/ig, '.'), s = $(this).attr('rel'), t = $(this).attr('title');
  		$(this).before('<a href="#" onclick="location.href=\'mailto:'+ c + (s ? '?subject='+ s : '') +'\'; return false;">'+ (t && t != '' ? t : c) +'</a>').remove();
  	});
  }).trigger('e_obf.load');

});
