//
//  File:       application.js
//
//  Synopsis:   Main entry point for application
//
//----------------------------------------------------------------------------

// Set up our namespace
var m = new Object();

// Global app object
var app = null;
var player = null;
var lyric = null;
var persist = null;
var user = null;
var dialog = null;


//
// Cross-browser solution for triggering init after the page loads but before
// external resources (e.g. images) are loaded.  From http://dean.edwards.name/weblog/2006/06/again/.
//
function init() {
  // Quit if this function has already been called
  if (arguments.callee.done)
    return;
  
  // Flag this function so we don't do the same thing twice
  arguments.callee.done = true;
  
  // kill the timer
  if (_timer)
  {
    clearInterval(_timer);
    _timer = null;
  }

  // Create the app and get things rolling
  app = new m.App();
};

/* For Mozilla */
if (document.addEventListener) {
  document.addEventListener("DOMContentLoaded", init, false);
}

/* For Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
  var dummy = location.protocol == "https:" ? "https://javascript:void(0)" : "javascript:void(0)";
  document.write("<script id=__ie_onload defer src='" + dummy + "'><\/script>");
  var script = document.getElementById("__ie_onload");
  script.onreadystatechange = function() {
    if (this.readyState == "complete") {
      init(); // call the onload handler
    }
  };
/*@end @*/

/* For Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
  var _timer = setInterval(function() {
    if (/loaded|complete/.test(document.readyState)) {
      init(); // call the onload handler
    }
  }, 10);
}

function window_onload()
{
  init();
}

window.onload = window_onload;

function window_onbeforeunload()
{
	if (player != 'undefined') { player.stop(); player.close(); }
}

window.onbeforeunload = window_onbeforeunload;


document.onmousedown = function(event) {
	if ((loader = document.ajax_loader) && loader.transport.readyState <= 3) { loader.transport.abort(); loader.options.onSuccess = null; loader.options.onComplete(); }
	if (window.event ? (window.event.button != 0 && window.event.button != 1) : (event.button != 0)) return true;
	var a = (window.event && window.event.srcElement) ? window.event.srcElement : event.target;
	if (a && a.tagName && a.tagName.toLowerCase() != 'a' && !a.onclick) a = a.parentElement ? a.parentElement : a.parentNode;
	if (a && a.tagName && a.tagName.toLowerCase() != 'a' && !a.onclick) a = a.parentElement ? a.parentElement : a.parentNode;
	if (!a || !a.tagName || a.tagName.toLowerCase() != 'a' || a.href.toLowerCase().indexOf('javascript')>-1 || a.href == '#' || a.onclick) return true;
	if (!(new RegExp(location.host)).test(a.href)) { a.target = '_blank'; return true; }
	if (/^_/.test(a.target)) return true;
	if (typeof(dhtmlHistory) == 'undefined') return true;
	if (!$(a.target || 'body')) return true;
	
	if (a.onmousedown) return true;
	
	histoy_handler(a.href.replace(/^http:\/\/[^\/]+/,''), { 'target': (a.target || 'body') });
	return false;
}

document.onclick = function(event) {
	if ($$('body')[0].hasClassName('loading')) return false;
	if (window.event ? (window.event.button != 0 && window.event.button != 1) : (event.button != 0)) return true;
	var a = (window.event && window.event.srcElement) ? window.event.srcElement : event.target;
	if (a && a.tagName && a.tagName.toLowerCase() != 'a' && !a.onclick) a = a.parentElement ? a.parentElement : a.parentNode;
	if (a && a.tagName && a.tagName.toLowerCase() != 'a' && !a.onclick) a = a.parentElement ? a.parentElement : a.parentNode;
	if (!a || !a.tagName || a.tagName.toLowerCase() != 'a' || a.href.toLowerCase().indexOf('javascript')>-1 || a.href == '#' || a.onclick) return true;
	if (!(new RegExp(location.host)).test(a.href)) { a.target = '_blank'; return true; }
	if (/^_/.test(a.target)) return true;
	if (typeof(dhtmlHistory) == 'undefined') return true;
	if (!$(a.target || 'body')) return true;
	
	if (!a.onmousedown) return false;
	
	histoy_handler(a.href.replace(/^http:\/\/[^\/]+/,''), { 'target': (a.target || 'body') });
	return false;
}

Event.observe(window, 'popstate', function(event) {
	state = window.history.state || event.state;
	if (!state || window.history.ver && window.history.ver == state['ver']) return;
	histoy_handler(state['url'], { keep: true });
});

var histoy_handler = function(href, options) {
	options = options || {};
	if (href == '') href = document.location.href.replace(/^http:\/\/[^\/]+/,'');
	href = href.replace(/^!/,'');
	
	document.ajax_loader = new m.Ajax.Request(href, {
		asynchronous: true,
		method: options['method'] || 'get',
		parameters : options['parameters'] || '',
		contentType: 'text/html',
		onCreate: function() {
			$$('body')[0].addClassName('loading');
			document.original_title = document.original_title || document.title;
		},
		onComplete: function() {
			$$('body')[0].removeClassName('loading');
		},
		onFailure: function() {
			document.location = href;
		},
		onSuccess: function(response) {
			if (!response.responseText.length) return;
			try {
				target = options['target'] || 'body';
				if (target != 'body' && !$(target)) target = 'body';
				// $(target).fade({ duration: 0.3, from: 1, to: 0.7 });
				if (-$(target).viewportOffset().top > 100) Effect.ScrollTo(target, { duration: '0.3' });
				// setTimeout(function(){
					var html = response.responseText;
					div = (new RegExp("div_"+target+"_begin -->([\\s\\S]+)<!-- div_"+target+"_end","")).exec(html)[1];
					document.new_title = (r = /<title>(.+)<\/title>/.exec(html.substring(0,600))) ? r[1] : '爱听';
					$(target).update(div);
					player.load();
					persist.load();
					user.load();
					m.Reply.init();
					new m.Invite();
					dialog = new m.Dialog();
					
					$$('.prefetch').each(function(a){
						if (a.prefetch_bind) return;
						a.prefetch_bind = true;
						Event.observe(a, 'mouseover', function(event){
							if (this.prefetch_done || $$('body')[0].hasClassName('loading')) return;
							this.prefetch_done = true;
							new Ajax.Request(this.href, { method: 'get' });
						});
					});
					
					if (r = /<link rel="prerender" href="([^"]+)" \/><link rel="prefetch" href="([^"]+)" \/>/.exec(html.substring(0,600))) setTimeout(function(){ new Ajax.Request(r[1],{method:'get'}); }, 500);
					if (!options['keep']) window.history.replaceState ? window.history.pushState({ ver: (window.history.ver = parseInt(Math.random()*100000000)), url: decodeURIComponent(href) }, '', decodeURIComponent(href)) : dhtmlHistory.add('!'+href);
					document.title = document.original_title = document.new_title ||  document.original_title;
					if (typeof(_gaq) != 'undefined' && _gaq) _gaq.push(['_trackPageview', href]);
					// $(target).appear({ duration: 0.3, from: 0.7, to: 1 });
				// }, 300);
			} catch(e) {
				document.location = href;
			}
		}
	});
}

Event.observe(window, 'dom:loaded', function() {
	window.history.replaceState ? window.history.replaceState({ ver: (window.history.ver = parseInt(Math.random()*100000000)), url: decodeURIComponent(document.location.href) }, '', decodeURIComponent(document.location.href)) : dhtmlHistory.add('!'+href);
	if (typeof(dhtmlHistory) != 'undefined') {
		dhtmlHistory.initialize();
		dhtmlHistory.addListener(histoy_handler);
	}
});




//
// This is overridden for the html integration script but just use Prototype's Ajax directly here
//
m.Ajax = Ajax;

m.Cookie = EasyCookie=(function(){var EPOCH='Thu, 01-Jan-1970 00:00:01 GMT',RATIO=1000*60*60*24,KEYS=['expires','path','domain'],esc=escape,un=unescape,doc=document,me;var get_now=function(){var r=new Date();r.setTime(r.getTime());return r;}
var cookify=function(c_key,c_val){var i,key,val,r=[],opt=(arguments.length>2)?arguments[2]:{};r.push(esc(c_key)+'='+esc(c_val));for(i=0;i<KEYS.length;i++){key=KEYS[i];if(val=opt[key])
r.push(key+'='+val);}
if(opt.secure)
r.push('secure');return r.join('; ');}
var alive=function(){var k='__EC_TEST__',v=new Date();v=v.toGMTString();this.set(k,v);this.enabled=(this.remove(k)==v);return this.enabled;}
me={set:function(key,val){var opt=(arguments.length>2)?arguments[2]:{},now=get_now(),expire_at,cfg={};if(opt.expires){opt.expires*=RATIO;cfg.expires=new Date(now.getTime()+opt.expires);cfg.expires=cfg.expires.toGMTString();}
var keys=['path','domain','secure'];for(i=0;i<keys.length;i++)
if(opt[keys[i]])
cfg[keys[i]]=opt[keys[i]];var r=cookify(key,val,cfg);doc.cookie=r;return val;},has:function(key){key=esc(key);var c=doc.cookie,ofs=c.indexOf(key+'='),len=ofs+key.length+1,sub=c.substring(0,key.length);return((!ofs&&key!=sub)||ofs<0)?false:true;},get:function(key){key=esc(key);var c=doc.cookie,ofs=c.indexOf(key+'='),len=ofs+key.length+1,sub=c.substring(0,key.length),end;if((!ofs&&key!=sub)||ofs<0)
return null;end=c.indexOf(';',len);if(end<0)
end=c.length;return un(c.substring(len,end));},remove:function(k){var r=me.get(k),opt={expires:EPOCH};doc.cookie=cookify(k,'',opt);return r;},keys:function(){var c=doc.cookie,ps=c.split('; '),i,p,r=[];for(i=0;i<ps.length;i++){p=ps[i].split('=');r.push(un(p[0]));}
return r;},all:function(){var c=doc.cookie,ps=c.split('; '),i,p,r=[];for(i=0;i<ps.length;i++){p=ps[i].split('=');r.push([un(p[0]),un(p[1])]);}
return r;},version:'0.2.1',enabled:false};me.enabled=alive.call(me);return me;}());


//----------------------------------------------------------------------------
//
// m.App class
//
//----------------------------------------------------------------------------

m.App = Class.create();

m.App.prototype = {

	// Initialize
	initialize: function() {
		app = this;
		user = new m.User();
		player = new m.Player();
		lyric = new m.Lyric();
		persist = new m.Persist();
		dialog = new m.Dialog();
		invite = new m.Invite();
		m.Reply.init();
		
		Event.observe(window, 'scroll', function(){
			if ($$('body')[0].hasClassName('loading') || !(a = $$('a.more_page')[0]) || ((document.documentElement||document.body).clientHeight - a.viewportOffset().top < 50)) return true;
			a.addClassName('loading');
			histoy_handler('!'+a.href.replace(/^http:\/\/[^\/]+/,''), { target: a.target, keep: true });
		});
		
		$$('.prefetch').each(function(a){
			if (a.prefetch_bind) return;
			a.prefetch_bind = true;
			Event.observe(a, 'mouseover', function(event){
				if (this.prefetch_done || $$('body')[0].hasClassName('loading')) return;
				this.prefetch_done = true;
				new Ajax.Request(this.href, { method: 'get' });
			});
		});
		
		$$('body')[0].removeClassName('loading');
	},
	
	ping: function(url) {
		var image = new Image();
		image.src = url;
		image.width = 0;
		image.height = 0;
		document.body.insertBefore(image, document.body.firstChild);
	},
	
	get_swf_id: function(swf_id) {
		if (navigator.appName.indexOf("Microsoft") > -1) return window[swf_id];
		else return document[swf_id];
	}
};



//----------------------------------------------------------------------------
//
// m.User class
//
//----------------------------------------------------------------------------

m.User = Class.create();

m.User.prototype = {
  initialize: function() {
		this.load();
	},
	
	load: function() {
		this.id = m.Cookie.get('user_id');
		this.name = decodeURIComponent(m.Cookie.get('user_name'));
		this.pic = m.Cookie.get('user_pic');
		this.inbox = m.Cookie.get('user_inbox');
		
		if (this.login()) {
			if ($('welcome_bar')) $('welcome_bar').update('<img width=20 height=20 style="vertical-align:top;" src="'+this.pic+'" />Hi <a href="/users/'+this.id+'/" title="">'+this.name+'</a> <a title="收件箱" style="color:'+(this.inbox==0 ? 'gray' : '#FF690A')+';" href="/home/inbox/">('+this.inbox+')</a> <a href="/logout/" target="_self" style="font-size:10px;color:gray;" onclick="return confirm(\'确定退出吗？\');">退出</a>');
		} else {
			if ($('welcome_bar')) $('welcome_bar').update('<a href="/login/" onclick="dialog.onClickLogin(); event.returnValue = false; return false;">登录</a> 或 <a target="_self" href="/signup/">免费注册</a>');
			if ($('homepage_banner')) $('homepage_banner').show();
		}
	},
	
	login: function() {
		return !!this.id;
	}
};

	
//----------------------------------------------------------------------------
//
// m.Player class
//
//----------------------------------------------------------------------------

m.Player = Class.create();

m.Player.prototype = {
	
  initialize: function() {
		this.cur_id = null;
		this.cur_song = null;
		this.cur_time = null;
		this.timer = null;
		this.win = null;
		this.playing = false;
		this.list = [];
		this.data = {};
		this.expandos = {};
		this.cur_expando = null;
		this.play_tip = $('play_tip');
		this.play_button = $('play_button');
		this.prev_button = $('prev_button');
		this.next_button = $('next_button');
		if (this.play_button) Event.observe(this.play_button, "click", this.toggle.bind(this), false);
		if (this.prev_button) Event.observe(this.prev_button, "click", this.prev.bind(this), false);
		if (this.next_button) Event.observe(this.next_button, "click", this.next.bind(this), false);
		this.load();
	},
	
	load: function() {
		this.list = [];
		var doms = $$('.song_title > a');
		for (var i=0;i<doms.length;i++) {
			var data = doms[i].onkeydown();
			this.list[i] = data.dom_id;
			this.data[data.dom_id] = data;
		}
	},
	
	click: function(id) {
		if (this.data[id]['duration'] <= 0) {
			this.expand(id);
			return;
		}
		
		if (!user.login()) {
			dialog.onClickLogin();
			return;
		}
			
		if (this.playing && id == this.cur_id) {
			this.stop(); 
			this.close();
		} else {
			this.stop();
			this.close();
			this.play(id);
		}
	},
	
	open:function(url) {
		try {
			if (!this.win) {
				this.win = window.open('about:blank', '', 'width=320,height=160,top=10000,left=10000,toolbar=no,menubar=no,scrollbars=no,resizable=yes,location=no,status=no,alwaysLowered=yes');
				if (this.win) {
					this.win.opener = null;
					this.win.blur();
					window.focus();
				}
			}
			if (this.win) this.win.location = url;
		} catch(e) {
			this.win = null;
		}
		
		return !!this.win;
	},
	
	close: function() {
		try {
			if (this.win) this.win.close();
			this.win = null;
		} catch(e) {
			return false;
		}
		return true;
	},
	
	play: function(id) {
		if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1 || navigator.userAgent.toLowerCase().indexOf('msie 8') > -1 || navigator.userAgent.toLowerCase().indexOf('opera') > -1) {
			this.expand(id);
			if ($(id+'_status')) {
				$(id+'_status').update('<style>.alert{color:red;}.alert a{color:red;text-decoration:underline;}</style><span class="alert">此浏览器不支持播放，请使用'+$('browser_list').innerHTML+'</span>');
			} else {
				alert('此浏览器不支持播放。请使用火狐浏览器');
			}
			return;
		}
		
		if (this.playing && !this.stop()) {
			return;
		}
		
		if (this.data[id]['duration'] == 0) {
			this.cur_id = id;
			this.next();
			return;
		}
		
		this.cur_id = id;
		this.cur_song = this.data[id];
		this.cur_btn = $(id+'_play_btn');
		this.cur_bar = $(id+'_progress_bar');
		this.cur_bar_container = $(id+"_progress_bar_container");
		this.cur_scroll_container = $(id + "_scroll_container");
		this.cur_scroll_content = $(id + "_scroll_content");
		this.cur_marker_el = $(id+"_float_marker");
		this.cur_time = null;
		
		var success = this.open('/redirects?http://www.1ting.com/player/34/player_'+this.cur_song['id']+'.html');
		if (success) {
			this.playing = true;
			this.prepare();
			this.timer = setInterval(this.update.bind(this), 500);
			this.expand(id);
			document.original_title = document.title;
			document.title = '► '+this.cur_song['name']+' by '+this.cur_song['artist_name']+' - '+document.original_title;
			if (this.cur_btn) this.cur_btn.className = 'song_play_btn_loading';
			if (this.play_tip) this.play_tip.update('<a href="/music/tracks/'+this.cur_song['id']+'/">'+this.cur_song['name']+'</a> by <a href="/music/artists/'+this.cur_song['artist_id']+'/">'+this.cur_song['artist_name']+'</a>');
			if (this.play_button) this.play_button.className = 'play-button loading';
			new m.Ajax.Request('/tracks/'+this.cur_song['id']+'/hit/', {
				method: 'post',
				parameters: (this.cur_song['ext_type'] ? { 'ext_type':this.cur_song['ext_type'], 'ext_id':this.cur_song['ext_id'], 'ext_user_id':this.cur_song['ext_user_id'] } : {})
			});
		}
	},
	
	stop: function() {
		if (!this.playing) return true;
		
		var success = (navigator.userAgent.toLowerCase().indexOf('msie 9') > -1) ? this.close() : this.open('about:blank');
		
		if (true) {
			this.playing = false;
			clearInterval(this.timer);
			if (this.cur_btn) this.cur_btn.className = 'song_play_btn';
			if (this.cur_bar) {
				this.cur_bar.style.borderRight = "none";
				this.cur_bar.style.visibility = "hidden";
				this.cur_bar.style.width = 0;
			}
			document.title = document.original_title || '爱听';
			if (this.play_tip) this.play_tip.update('');
			if (this.play_button) this.play_button.className = 'play-button';
		}
		return success;
	},
	
	next: function() {
		var next = this.find(1);
		if (next) this.play(next);
		else { this.stop(); this.close(); }
		
		this.autoload();
	},
	
	prev: function() {
		var next = this.find(-1);
		if (next) this.play(next);
		else { this.stop(); this.close(); }
		
		this.autoload();
	},
	
	toggle:function() {
		if (!this.playing) var next = this.find(0);
		if (next) this.play(next);
		else { this.stop(); this.close(); }
		
		this.autoload();
	},
	
	find:function(order) {
		if (this.list.length == 0) return null;
		if (!this.cur_id) return this.list[0];
		if (order == 0) return this.cur_id;
		return this.list[this.list.indexOf(this.cur_id)+order] || this.list[0];
	},
	
	autoload: function(){
		if (this.list[this.list.length-1] != this.cur_id) return;
		if ($$('body')[0].hasClassName('loading') || !(a = $$('a.more_page')[0])) return true;
		a.addClassName('loading');
		histoy_handler(a.href.replace(/^http:\/\/[^\/]+/,''), { 'target': a.target });
	},
	
	prepare: function() {		
		if (this.cur_bar_container) {
			var usable_width = 0;
			var marker_pos = Position.page(this.cur_marker_el)[0];
			var leftmost_pos = Position.page(this.cur_bar_container)[0];
			usable_width = marker_pos - leftmost_pos;
			
			// 23px for left-margin for the play button, 5px as padding on right
			if (this.cur_scroll_container) this.cur_scroll_container.style.width = "" + (usable_width - 28) + "px";
			if (this.cur_bar_container) this.cur_bar_container.style.width = "" + usable_width + "px";
		}
	},
	
	update: function() {
		if (!this.cur_time) {
			try {
				if (!this.win.location.href) throw 'e';
			} catch(e) {
				this.cur_time = new Date();
				if (this.cur_btn) this.cur_btn.className = 'song_play_btn_playing';
				if (this.play_button) this.play_button.className = 'play-button paused';
			}
		}
		if (!this.cur_time) return;
		
		var percentage = this.cur_song['duration'] > 0 ? ((new Date() - this.cur_time) / 10 / (this.cur_song['duration'])) : 0;
		
		if (percentage > 100) {
			if (this.stop()) this.next();
			return;
		}
		
		if (this.cur_bar) {
			if (percentage > 0) {
				full_width = this.cur_bar_container.getDimensions().width;
				bar_width = Math.round(full_width * (percentage / 100.0));
				
				if ((navigator.userAgent.indexOf('MSIE') != -1) && (document.compatMode == 'BackCompat')) {
	    		bar_width += 23;
				}
				
				this.cur_bar.style.borderRight = "solid 2px #cccccc";
				this.cur_bar.style.visibility = "visible";
				this.cur_bar.style.width = bar_width + "px";
			} else {
				this.cur_bar.style.borderRight = "none";
				this.cur_bar.style.visibility = "hidden";
				this.cur_bar.style.width = 0;
			}
		}
		
		if (lyric) {
			lyric.update(''+this.cur_id+'_tabcontent_lyric', (new Date() - this.cur_time)/1000);
		} 
	},
	
	expand: function(id) {
		if (this.expando(id)) {
			if (this.cur_expando) this.cur_expando.hide();
			this.expando(id).show();
			this.cur_expando = this.expando(id);
		}
	},
	
	expando: function(id) {
		if (!this.expandos[id]) this.expandos[id] = new m.Expando(id);
		return this.expandos[id];
	}
};





//----------------------------------------------------------------------------
//
// m.Expando class
//
//----------------------------------------------------------------------------

m.Expando = Class.create();

m.Expando.prototype = {
	
  initialize: function(id) {
		this.id = id;
		this.data = player.data[id];
		this.expando = $(id+'_expando');
		this.lastActiveTab = null;
		this.href = 'http://ilike001.com/tracks/'+this.data['id']+'/';
		this.title = this.data['name']+' by '+this.data['artist_name'];
		
		if (this.expando && this.expando.innerHTML.strip.length == 0) {
			this.expando.update(' \
				<ul class="expando_navlist"> \
					<li><a id="'+this.id+'_tab_info" href="#" rel="nofollow" class="current tabicon_album" style="padding-left:25px;" onmousedown="player.expando(\''+this.id+'\').tab(\'info\');" onclick="Event.stop(event);return false;" onfocus="this.blur();">专辑</a></li> \
					<li><a id="'+this.id+'_tab_pick" href="#" rel="nofollow" class="inactive tabicon_ilike" style="padding-left:25px;" onmousedown="player.expando(\''+this.id+'\').tab(\'pick\');" onclick="Event.stop(event);return false;" onfocus="this.blur();">推荐</a></li> \
					<li><a id="'+this.id+'_tab_share" href="#" rel="nofollow" class="inactive tabicon_send" style="padding-left:27px;" onmousedown="player.expando(\''+this.id+'\').tab(\'share\');" onclick="Event.stop(event);return false;" onfocus="this.blur();">送歌</a></li> \
					'+(!this.data['has_lyric?'] ? '' : '<li><a id="'+this.id+'_tab_lyric" href="#" rel="nofollow" class="inactive tabicon_findvideos" style="padding-left:27px;" onmousedown="player.expando(\''+this.id+'\').tab(\'lyric\');player.expando(\''+this.id+'\').lyric();" onclick="Event.stop(event);return false;" onfocus="this.blur();">歌词</a></li>')+' \
				</ul> \
				<div class="expando_content"> \
					<div id="'+this.id+'_tabcontent_info"> \
						<a href="/music/albums/'+this.data['album_id']+'/"><img id="'+this.id+'_album_img" class="song_album_image" src="'+(this.data['album_pic'] ? this.data['album_pic'] + '.100x100.jpg' : '/images/ilike/no_photo_100x100.gif')+'" width="100" height="100" alt="'+this.data['album_name']+'"/></a> \
						<div id="'+this.id+'_status" class="song_album_info"> \
							歌曲：<a href="/music/tracks/'+this.data['id']+'/">'+this.data['name']+'</a> \
							<br />专辑：<a href="/music/albums/'+this.data['album_id']+'/">'+this.data['album_name']+'</a> \
							<br />分享： \
							<a href="#" onclick="share(\'xiaonei\',\''+this.href+'\',\''+this.title+'\');Event.stop(event);return false;"><img src="/images/icons/xiaonei.png" />校内</a> \
							<a href="#" onclick="share(\'kaixin\',\''+this.href+'\',\''+this.title+'\');Event.stop(event);return false;"><img src="/images/icons/kaixin.png" />开心</a> \
							<a href="#" onclick="share(\'douban\',\''+this.href+'\',\''+this.title+'\');Event.stop(event);return false;"><img src="/images/icons/douban.png" />豆瓣</a> \
							<a href="#" onclick="share(\'qzone\',\''+this.href+'\',\''+this.title+'\');Event.stop(event);return false;"><img src="/images/icons/qzone.png" />QQ</a> \
						</div> \
					</div> \
					<div style="display: none; overflow: hidden;" id="'+this.id+'_tabcontent_pick"> \
						<div class="expando_tab_text"> \
							把这首歌推荐给你的所有好友 \
							<form method="POST" id="'+this.id+'_pick_form" action="/music/tracks/'+this.data['id']+'/recommend/"> \
								<textarea style="margin-top: 5px; margin-bottom: 5px; color: rgb(113, 119, 123);" name="content" id="'+this.id+'_pick_comment" class="expando_textarea"></textarea><br/> \
								<div id="'+this.id+'_pick_btn_area"><a onclick="player.expando(\''+this.id+'\').recommend(event); return false;" class="expando_button expando_button_large" href="#"><p>推荐歌曲</p></a></div> \
							</form> \
						</div> \
					</div> \
					<div style="display: none; overflow: hidden;" id="'+this.id+'_tabcontent_share"> \
						<div style="margin-left: 5px; line-height: 1.4em;"> \
							<form method="POST" class="expando_share_form" id="'+this.id+'_share_form" action="/music/tracks/'+this.data['id']+'/recommend/" onsubmit="return false;"> \
								<dl> \
									<dt><label class="expando_share_labels" for="'+this.id+'_share_users">送给：</label></dt> \
									<dd><div class="share_recipients share_recipients_pick_view"><div id="'+this.id+'_share_users"><select onmouseover="player.expando(\''+this.id+'\').select(event);" id="'+this.id+'_share_users_input" style="width:180px;"><option>&lt;请选择好友&gt;</option></select> <a href="/invites/">好友太少？去邀请好友</a></div></div></dd> \
									<dt><label class="expando_share_labels" for="'+this.id+'_share_comment">消息：</label></dt> \
									<dd><textarea style="color: rgb(113, 119, 123);" class="share_textarea" id="'+this.id+'_share_comment" name="content"></textarea></dd> \
									<dt></dt><dd><div style="" id="'+this.id+'_share_btn_area"><a onclick="player.expando(\''+this.id+'\').share(event); return false;" class="expando_button expando_button_medium" href="#"><p>送这首歌</p></a></div></dd> \
								</dl> \
							</form> \
						</div> \
					</div> \
					<div id="'+this.id+'_tabcontent_lyric" style="display:none; height:110px;"></div> \
				</div> \
			');
		}
		
		this.show();
		this.tab('info');
	},
	
	show: function() {
		if (this.expando) this.expando.show();
	},
	
	hide: function() {
		if (this.expando) this.expando.hide();
	},
	
	toggle: function() {
		if (this.expando) {
			if (this.expando.display == 'none') this.show();
			else this.hide();
		}
	},
	
	tab: function(tab) {
		if ($(this.id + "_tab_" + tab)) {
			$(this.id + "_tab_" + tab).addClassName('current');
			$(this.id + "_tab_" + tab).removeClassName('inactive');
			if (this.lastActiveTab && this.lastActiveTab != tab) {
        $(this.id + "_tabcontent_" + this.lastActiveTab).hide();
        $(this.id + "_tab_" + this.lastActiveTab).addClassName("inactive");
        $(this.id + "_tab_" + this.lastActiveTab).removeClassName("current");
      }
			$(this.id + "_tabcontent_" + tab).show();
      this.lastActiveTab = tab;
		}
	},
	
	recommend: function() {
		if (!user.login()) {
			dialog.onClickLogin();
			return false;
		}
		var form = $(''+this.id+'_pick_form');
		var btn = $(this.id+'_pick_btn_area');
		new Ajax.Request(form.action, {
			asynchronous: true,
			evalScripts: false,
			parameters: Form.serialize(form),
			onLoading: function() {
				btn.update('发送中');
			},
			onFailure: function() {
				btn.update('发送失败');
			},
			onSuccess: function() {
				btn.update('推荐成功！');
			}
		});
	},
	
	select: function() {
		var id = this.id;
		$(''+this.id+'_share_users_input').disabled = true;
		new Ajax.Request('/home/friends_json', {
			asynchronous: true,
			evalScripts: false,
			onSuccess: function(resp) {
				var html = '<select name="target_id" style="width:180px;">'+eval('('+resp.responseText+')').map(function(u){return '<option value="'+u['id']+'">'+u['name']+'</option>';}).join('')+'</select> <a href="/invites/">好友太少？去邀请好友</a>';
				$(''+id+'_share_users').update(html);
			}
		});
	},
	
	share: function() {
		if (!user.login()) {
			dialog.onClickLogin();
			return false;
		}
		var form = $(''+this.id+'_share_form');
		var btn = $(this.id+'_share_btn_area');
		new Ajax.Request(form.action, {
			asynchronous: true,
			evalScripts: false,
			parameters: Form.serialize(form),
			onLoading: function() {
				btn.update('发送中');
			},
			onFailure: function() {
				btn.update('发送失败');
			},
			onSuccess: function() {
				btn.update('送歌成功！');
			}
		});
	},
	
	lyric: function() {
		if ($(''+this.id+'_tabcontent_lyric').innerHTML.empty()) {
			new Ajax.Request('/tracks/'+this.data['id']+'/lyric/', {
				asynchronous: true,
				evalScripts: false,
				method: 'get',
				onSuccess: (function(resp) {
					if ($(''+this.id+'_tabcontent_lyric')) $(''+this.id+'_tabcontent_lyric').update(resp.responseText);
				}).bind(this)
			});
		}
	}
};


//----------------------------------------------------------------------------
//
// m.Lyric class
//
//----------------------------------------------------------------------------

m.Lyric = Class.create();

m.Lyric.prototype = {
	initialize: function() {},
	update: function(song, time) {
		if (!($(song) && $(song).visible())) return;
		
		this.data = this.data || {};
		this.data[song] = this.data[song] || {};
		if (!this.data[song]['times'] || this.data[song]['times'].length == 0) this.data[song]['times'] = $$('#'+song+' p[rel]').map(function(p){return p.readAttribute('rel')});
		
		if (!(
			(this.data[song]['times'].length > 0) &&
			(t = this.data[song]['times'].find(function(t){return parseFloat(t)>time;})) && 
			(content = $$('#'+song+' .content')[0]) && 
			(line = $$('#'+song+' p[rel='+t+']')[0]) &&
			(line != this.data[song]['current']) &&
			(line.offsetTop >= content.scrollTop && line.offsetTop + line.clientHeight <= content.scrollTop + content.clientHeight || time < 5)
		)) return;
		
		if (this.data[song]['current']) this.data[song]['current'].writeAttribute('style', '');
		line.writeAttribute('style', 'color:#FF690A;font-weight:bold;');
		this.data[song]['current'] = line;
		content.scrollTop = line.offsetTop - (content.clientHeight - line.clientHeight)/2;
	}
}


//----------------------------------------------------------------------------
//
// m.Persist class
//
//----------------------------------------------------------------------------

m.Persist = Class.create();

m.Persist.prototype = {
  initialize: function() {
		if (user.login()) {
			Persist.remove('gears');
			this.store = new Persist.Store('persist', { swf_path: '/javascripts/persist.swf' });
		}
		
		this.load();
	},
	
	load: function(resp) {
		if (!user.login()) {
			p = $$('.persist');
			for (i=0;i<p.length;i++) { 
				p[i].addClassName('inactive'); 
				p[i].onclick = function() { dialog.onClickLogin(); return false; } 
			}
			return;
		}
		
		if (Persist.type == 'flash' && !app.get_swf_id('_persist_flash').get) {
			setTimeout("persist.load()", 300);
			return;
		} 
		
		if (resp) {
			this.store.set('persist_data', resp.responseText);
			this.ready(true, resp.responseText);
		} else {
			this.store.get('persist_data', this.ready.bind(this));
		}
	},
	
	ready: function(ok, val) {
		if (ok && val) try { this.data = eval('('+val+')'); } catch(e) {}
		
		if (!this.data || this.data['meta'] != m.Cookie.get('persist_meta')) {
			new Ajax.Request('/home/persist', { onComplete: this.load.bind(this) });
			return;
		}
		
		p = $$('.persist');
		for (i=0;i<p.length;i++) {
			type = p[i].readAttribute('type');
			id = p[i].readAttribute('rel');
			p[i].addClassName(this.data[type].include(id) ? 'active' : 'inactive');
			if (user.id == p[i].readAttribute('user_id')) p[i].hide();
			p[i].onclick = function() { this.blur(); return false; }
			p[i].onmousedown = function() {
				if (this.hasClassName('loading')) return;
				type = this.readAttribute('type');
				id = this.readAttribute('rel');
				active = this.hasClassName('inactive') ? 1 : 0;
				e = $(this);
				new Ajax.Request('/'+(active ? 'like' : 'hate')+'/'+type+'/'+id+'/', {
					onLoading: function() {
						e.addClassName('loading');
					},
					onComplete: function() {
						e.removeClassName('loading');
					},
					onSuccess: function() {
						if (active == 1) e.addClassName('active').removeClassName('inactive');
						else e.addClassName('inactive').removeClassName('active');
						
						if (active == 1 && type == 'friend') { e.addClassName('loading'); $('friend_add').hide(); $('friend_remove').hide(); $('friend_waiting').style.display = 'block'; }
					}
				})
			}
		}
	}
};



//----------------------------------------------------------------------------
//
// m.Dialog class
//
//----------------------------------------------------------------------------

m.Dialog = Class.create();

m.Dialog.prototype = {

  initialize: function(prefix) {
    this.prefix = prefix || 'login';
    this.dialog = $(this.prefix + '_dialog');
    
		if (this.dialog) {
			Event.observe(this.dialog, 'keypress', this.onKeyPress.bind(this), false);
	    Event.observe(this.prefix + '_close', 'click', this.onClickClose.bind(this), false);
		}
  },

  onClickClose: function(ev) {
    this.hideDialog();
    Event.stop(ev);
  },

  onClickLogin: function(ev) {
    // Observe close clicks
    Event.observe('login_overlay', 'mousedown', this.hideDialog.bind(this), false);

    // Compute new positions
    var scrollOffsets = document.viewport.getScrollOffsets();
    var dialogStyle = {};
    dialogStyle.top = "" + ([document.viewport.getHeight() - this.dialog.getHeight(), 125].min() + scrollOffsets[1]) + "px";
    dialogStyle.left = "" + ((document.body.offsetWidth - this.dialog.getWidth())/2) + "px";
    this.dialog.setStyle(dialogStyle);
    $('login_overlay').style.height = get_overlay_height();

    // Display sign-in form and overlay div
    this.dialog.show();
    $('login_overlay').show();
    
    window.onscroll = function(){
      $('login_overlay').style.height = get_overlay_height();
    }
    
    if ($(this.prefix + '_email')) {
      // Set focus to email field
      setTimeout(function() {$(this.prefix + '_email').focus();}.bind(this), 1);
    }

    // // Hide music tastes flash widget if it's on the page
    // if ($('my_plays_summary'))
    //   $('my_plays_summary').style.visibility = "hidden";

    if (ev) {
      Event.stop(ev);
    }
  },
  
  onKeyPress: function(ev) {
    var esc = window.event ? 27 : ev.DOM_VK_ESCAPE;
    var key = window.event ? event.keyCode : ev.keyCode;
    if (key == esc)
      this.hideDialog();
  },

  hideDialog: function() {
    this.dialog.hide();
    $('login_overlay').hide();


    // // Show music tastes if it's on the page
    // if ($('my_plays_summary'))
    //   $('my_plays_summary').style.visibility = "";
  }

};


function get_overlay_height() {
  // Return the new style attribute for the login overlay by calculating the
  // height of the viewing area, adding the scroll offset, and appending 'px'
  overlay_height = document.viewport.getHeight()+document.viewport.getScrollOffsets()[1];
  return ''+overlay_height+'px';
}


//----------------------------------------------------------------------------
//
// m.Reply class
//
//----------------------------------------------------------------------------
m.Invite = Class.create();
m.Invite.prototype = {
	initialize: function() {
		var t = this;
		this.options = ['ci0', 'ci1', 'ci2', 'ci3', 'ci4', 'ci5', 'ci6', 'ci7', 'ci8', 'invite_manually'];
		this.options.each(function(a){
			if ($(a+'_expando_select')) {
				$(a+'_expando_select').onclick = function() {
					if (t.current) {
						$(t.current+'_expando').hide();
						$(t.current+'_expando_select').show();	
					}
					t.current = a;
					$(a+'_expando').show();
					$(a+'_expando_select').hide();
					return false;
				}	
			}
		});
	}
}


//----------------------------------------------------------------------------
//
// m.Reply class
//
//----------------------------------------------------------------------------

m.Reply = Class.create();

m.Reply.byId = function(id) { return m.Reply.hash[id]; };

m.Reply.init = function() {
	m.Reply.hash = new Hash;
	$$('.pick_reply').each(function(d){
		data = d.onkeydown();
		id = data['id'];
		m.Reply.hash[id] = new m.Reply(id, data);
	});
} 

m.Reply.prototype = {

  initialize: function(id, data) {
		this.id = id;
		this.data = data;
		
		if (this.data['count'] > 0) this.load();
	},
	
	load: function() {
		if ($('pick_reply'+this.id).innerHTML != '') return true;
		this.href = 'http://www.ilike001.com/recommends/'+this.id+'/'
		div_start = ' \
			<form ajaxify="1" class="commentable_item one_row_add_box autoexpand_mode" id="commentable_item'+this.id+'" name="add_comment" action="/comments/" method="POST"> \
				<input type="hidden" name="comment[feed_id]" value="'+this.id+'" /> \
				<i class="GenericStory_Icon img spritemap_icons sx_icons_note"></i> \
				<div class="comment_box"> \
					<div class="comment_box_nub"></div> \
					<div class="feed_share" id="feed_share'+this.id+'"></div> \
					<div class="feed_comments" id="feed_comments'+this.id+'"> \
		'
		div_more = (this.data['count'] == 0 || this.data['count'] == this.data['comments'].size()) ? '' : ' \
			<div class="UIImageBlock clearfix ufi_section"> \
				<a href="/music/recommends/'+this.id+'/" onclick="m.Reply.byId('+this.id+').all();Event.stop(event);return false;">查看所有 '+this.data['count']+' 条评论</a> \
			</div> \
		'
		div_comments = this.data['comments'].map(function(c){
			return ' \
				<div id="comment_" class="ufi_section  UIImageBlock clearfix"> \
					<a title="'+c['user_name']+'" class="UIImageBlock_Image UIImageBlock_SMALL_Image" href="/users/'+c['user_id']+'/"> \
						<img src="'+c['user_pic']+'" class="UIProfileImage UIProfileImage_SMALL img"/> \
					</a> \
					<div class="UIImageBlock_Content UIImageBlock_SMALL_Content"> \
						<div class="comment_text"> \
							<a class="comment_author" href="/users/'+c['user_id']+'/">'+c['user_name']+'</a> \
							<div class="comment_actual_text"> \
								'+c['content'].replace(/\n/g,'<br/>')+' \
							</div> \
						</div> \
						<div class="comment_actions"></div> \
					</div> \
				</div> \
			'
		}).join('')
		div_end = ' \
					</div> \
					<div class="ufi_section comments_add_box clearfix" id="comments_add_box'+this.id+'"> \
						<textarea placeholder="" class="add_comment_text  DOMControl_autogrow   DOMControl_placeholder" id="add_comment_text'+this.id+'" name="comment[content]" onfocus="$(\'add_comment_text'+this.id+'\').removeClassName(\'DOMControl_placeholder\');$(\'add_comment_img'+this.id+'\').show();$(\'add_comment_button'+this.id+'\').show();" onblur="if($(\'add_comment_text'+this.id+'\').value.strip() == \'\'){$(\'add_comment_text'+this.id+'\').addClassName(\'DOMControl_placeholder\');$(\'add_comment_img'+this.id+'\').hide();$(\'add_comment_button'+this.id+'\').hide();}"></textarea> \
						<img style="display:none;" id="add_comment_img'+this.id+'" src="'+(user.login() ? user.pic : '/images/ilike/no_artist_photo_50x50.gif')+'" class="UIProfileImage UIProfileImage_SMALL img"/> \
						<a id="add_comment_button'+this.id+'" class="expando_button expando_button_tiny" href="#" onclick="m.Reply.byId('+this.id+').submit();Event.stop(event);return false;" style="display:none; float:left; margin:5px 0 0 40px;"><p>评论</p></a> \
					</div> \
				</div> \
			</form> \
		'
		
		$('pick_reply'+this.id).update(div_start+div_more+div_comments+div_end);
	},
	
	ready: function() {
		this.load();
		// this.share();
		$('add_comment_text'+this.id).focus();
	},
	
	share: function() {
		if (!$('feed_share'+this.id)) this.load();
		if ($('feed_share'+this.id).innerHTML != '') return;
		$('feed_share'+this.id).update(' \
			<div class="UIImageBlock clearfix ufi_section"> \
				分享到<a href="#" onclick="share(\'xiaonei\',\''+this.href+'\',null);Event.stop(event);return false;"><img style="vertical-align:middle;" src="/images/icons/xiaonei.png" />校内</a> \
				<a href="#" onclick="share(\'kaixin\',\''+this.href+'\',null);Event.stop(event);return false;"><img style="vertical-align:middle;" src="/images/icons/kaixin.png" />开心</a> \
				<a href="#" onclick="share(\'douban\',\''+this.href+'\',null);Event.stop(event);return false;"><img style="vertical-align:middle;" src="/images/icons/douban.png" />豆瓣</a> \
				<a href="#" onclick="share(\'qzone\',\''+this.href+'\',null);Event.stop(event);return false;"><img style="vertical-align:middle;" src="/images/icons/qzone.png" />QQ</a> \
			</div> \
		');
	},
	
	all: function() {
		var t = this;
		new Ajax.Request('/comments/?feed_id='+this.id, {
			method: 'get',
			onSuccess: function(response){
				var comments = eval(response.responseText);
				
				$('feed_comments'+t.id).update(comments.map(function(c){
					return ' \
						<div id="comment_" class="ufi_section  UIImageBlock clearfix"> \
							<a title="'+c['user_name']+'" class="UIImageBlock_Image UIImageBlock_SMALL_Image" href="/users/'+c['user_id']+'/"> \
								<img src="'+c['user_pic']+'" class="UIProfileImage UIProfileImage_SMALL img"/> \
							</a> \
							<div class="UIImageBlock_Content UIImageBlock_SMALL_Content"> \
								<div class="comment_text"> \
									<a class="comment_author" href="/users/'+c['user_id']+'/">'+c['user_name']+'</a> \
									<div class="comment_actual_text"> \
										'+c['content'].replace(/\n/g,'<br/>')+' \
									</div> \
								</div> \
								<div class="comment_actions"></div> \
							</div> \
						</div> \
					'
				}).join(''));
			}
		});
	},
	
	submit: function() {
		if (!user.login()) {
			dialog.onClickLogin();
			return false;
		}
		var t = this;
		new Ajax.Request($('commentable_item'+this.id).action, { 
			parameters: Form.serialize($('commentable_item'+this.id)), 
			onLoading: function(){
				$('add_comment_text'+t.id).disabled = true;
			},
			onSuccess: function(){
				$('feed_comments'+t.id).innerHTML += ' \
					<div id="comment_" class="ufi_section  UIImageBlock clearfix"> \
						<a title="'+user.name+'" class="UIImageBlock_Image UIImageBlock_SMALL_Image" href="/users/'+user.id+'/"> \
							<img src="'+user.pic+'" class="UIProfileImage UIProfileImage_SMALL img"/> \
						</a> \
						<div class="UIImageBlock_Content UIImageBlock_SMALL_Content"> \
							<div class="comment_text"> \
								<a class="comment_author" href="/users/'+user.id+'/">'+user.name+'</a> \
								<div class="comment_actual_text"> \
									'+$('add_comment_text'+t.id).value.replace(/\n/g,'<br/>')+' \
								</div> \
							</div> \
							<div class=\'comment_actions\'></div> \
						</div> \
					</div> \
				'; 
				$('add_comment_text'+t.id).value = '';
				$('add_comment_text'+t.id).disabled = false;
				$('add_comment_text'+t.id).onblur();
			} 
		}); 
		return false;
	}
};


