// mrdaio:ext.js
//
// mdario is freely distributable under the terms of new BSD license.
// Copyright (c) 2008-2009, makoto_kw (makoto.kw@gmail.com) All rights reserved.

// for ExtJS
if (Ext) {
	Ext.ns('mRadio.Ext');
	// patch for prototypejs/IE
	if (window.Event) {
		Object.extend(Event, {
			element: function(event){
				var node = Event.extend(event).target;
				return node && Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
			},
			pointer: function(event){
				return {
					x: event.pageX ||
					(event.clientX +
					((document && document.documentElement && document.documentElement.scrollLeft) ||
					(document && document.body && document.body.scrollLeft))),
					y: event.pageY ||
					(event.clientY +
					((document && document.documentElement && document.documentElement.scrollTop) ||
					(document && document.body && document.body.scrollTop)))
				};
			}
		});
	}
} // end of for ExtJS


mRadio.Ext.ControlPanel = function(config){
	this.isInitilaized = false;
	this.playerInitialized = false;
	this.player = config.player;
	this.ds = config.ds;
	this.cp = config.cp;
	
	var html='';
	// content details
	this.tplContentDetail = new Ext.XTemplate(
		'<div class="detail">',
			'<tpl for=".">',
				'<img class="thumbnail" src="{imgurl}" height="60">',
				'<div class="meta">',
					'<span class="title">{title}</span><span class="title_div">/</span><span class="artist">{artist}</span>',
					'<br/><span id="playtime">'+mRadio.resource.getString("LOADING_CONTENT")+'</span><span id="playtime_div"></span><span id="track_length"></span>',
				'</div>',
			'</tpl>',
		'</div>'
	);
	this.tplContentDetail.compile();
	var volume = this.cp.get("mradio_volume",20);
	var channel = this.cp.get("mradio_channel",config.channel);
	this.slrVolume = new Ext.Slider({isFormField:true,fieldLabel:'Volume',disabled:true,value:volume,increment:5,minValue:0,maxValue:100});
	this.slrChannel = new Ext.Slider({isFormField:true,fieldLabel:'Channel',disabled:true,value:channel,increment:10,minValue:0,maxValue:20});
	this.slrVolume.on({'change':{fn:function(silder,value){this.player.setVolume(value);},scope:this}});
	this.slrChannel.on({'change':{fn:function(silder,value){this.doLoadChannel(value);this.slrChannel.syncThumb();},scope:this}});
	
	this.firstChannel = channel;

	Ext.apply(config, {
		layout:'border',
		bodyStyle:'padding:2px',
		listeners:{
			'afterlayout':{fn:function(container,layout){
				var tryInit = function(){
					if (!this.isInitilaized) {
						Lyra.init("lyraSilverlightControlHost");
						this.player.start(Lyra);
						if (this.player.media != null) {
							this.player.media.on({
								'mediafailed': {fn: function(){this.doRandomPlay()},scope:this},
								'mediaended': {fn: function(){this.doRandomPlay()},scope:this}
							});
						}
						if (Lyra.isInitialized()) {
							this.player.setVolume(volume);
							this.playerInitialized = true;
							this.slrVolume.enable();
							this.slrVolume.syncThumb();
							this.initPlayButton();
							this.doRandomPlay();
						} else {
							this.displayNotSupported();
						}
						this.isInitilaized = true;
					}
				}
				tryInit.defer(2000, this);
			},scope:this}
		},
		border:true,
		defaults: {border:false,collapsible:false},
		items: [
		{
			id: 'control-header',
			region:'north',
			bodyStyle: 'padding-left:4px;border-bottom:1px solid #333;',
			height:20,
			html: '<div id="mradio-header"><div id="mradio-logo">mRadio</div>'
				+'<div id="mradio-player">'
					+'<a id="playpause-button" class="stopped" href="javascript:void(0)"></a>'
					+'<a id="next-button" href="javascript:void(0)"></a>'
				+'</div>'
				+'<div id="mradio-poweredby">Powered By <a href="http://mora.jp/">Mora</a> and <a href="http://api.x-jukebox.com/lyra/">Lyra</a></div></div>'
		},
		{
			layout:'border',
			region:'center',
			height:100,
			defaults:{border:false,bodyStyle: 'padding:4px 2px 2px 6px;'},
			items:[
				{
					layout: 'form',
					labelWidth: 45,
					width: 270,
					region:'east',
					defaults:{border:false},
					items: [this.slrVolume,this.slrChannel]
				},
				{id:'content-detail-panel', region:'center', html:'<p class="initializing">'+mRadio.resource.getString("INITIALIZING_PLAYER")+'</p>'}
			]
		},
		{
			html:
'<div id="silverlightControlHost">'
	+'<object width="0" height="0" id="lyraSilverlightControlHost" data="data:application/x-silverlight-2," type="application/x-silverlight-2">'
		+'<param name="source" value="/js/lyra/lyra.xap"/>'
		+'<param name="onerror" value="onSilverlightError" />'
		+'<param name="background" value="transparent" />'
		+'<param name="minRuntimeVersion" value="2.0.31005.0" />'
		+'<param name="autoUpgrade" value="true" />'
		+'<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">'
			+'<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>'
		+'</a>'
	+'</object>'
	+'<iframe style="visibility:hidden;height:0;width:0;border:0px"></iframe>'
+'</div>'
		}]
	});
	mRadio.Ext.ControlPanel.superclass.constructor.call(this, config);
	this.addEvents({playitemchanged:true});
};
Ext.extend(mRadio.Ext.ControlPanel, Ext.Panel, {
	displayNotSupported:function() {
		html = '<p class="warning">'+mRadio.resource.getString("NOT_SUPPORTED_BROWSER")+'</p>';
		var detailEl = Ext.get('content-detail-panel');
		detailEl.update(html);
	},
	doInitChannel: function() {
		this.doLoadChannel(this.firstChannel);
		this.slrChannel.enable();
		//this.slrChannel.setValue(hz); // fired changed and call doLoadChannel
	},
	doLoadChannel: function(hz) {
		var channel = this.getChannelName(hz)
		this.ds.load({params:{channel:channel}});
		this.cp.set("mradio_channel",hz);
	},
	getChannelName: function(hz) {
		var name = "morawin-all";
		if (hz==0) name = "morawin-all";
		else if (hz==10) name = "morawin-j";
		else if (hz==20) name = "morawin-e";
		return name;
	},
	
	doRandomPlay: function() {
		var count = this.ds.getCount();
		if (count==0) return false;
		if (!this.playerInitialized) return false;
		var index = Math.floor(Math.random()*count);
		var record = this.ds.getAt(index);
		if (record) this.doPlay(record.data);
	},
	
	playPause:function() {
		this.player.playPause();
		this.updatePlayButton();
	},
	
	skip:function() {
		this.doRandomPlay();
	},
	
	doPlay: function(content) {
		try {
			if (content) {
				if (!this.playerInitialized) return;
				
				// update detail
				var detailEl = Ext.getCmp('content-detail-panel').body; // TODO: id should be defined
				this.tplContentDetail.overwrite(detailEl, content);
			
				this.player.playUrl(content.mediaurl);
				
				var cid = 'c'+content.id;
				if (this.player.playingContentId != cid) {
					this.player.playingContentId = cid;
					this.fireEvent('playitemchanged',this,content);
				}
				
				this.update.defer(this.updateTimerDelay,this);
				
				//if (this.timeoutTimerID!==false) clearTimeout(this.timeoutTimerID);
				//this.timeoutTimerID = this.timeout.defer(10000,this);
			}
		} catch (ex) { }
	},
	
	timeoutTimerID:false,
	timeout: function() {
		if (ePlayerState_Stopped==this.player.getPlayerStatus()) {
			this.doRandomPlay();
		} else {
			this.timeoutTimerID = this.timeout.defer(2000,this);
		}
	},
	
	updateTimerDelay:1000,
	update: function() {
		var playTimeContainer = $('playtime');
		var divider = $('playtime_div');
		var trackLength = $('track_length');
		if (playTimeContainer && trackLength) {
			try {
				var t;
				// hack!
				var s = this.player.getPlayerStatus();
				if (s==ePlayerState_Opening) {
					pt = mRadio.resource.getString("LOADING_CONTENT");
					dv = "";
					tl = "";
				} else {
					pt = this.makeTimeString(this.player.getPlayerPosition());
					dv = "/";
					tl = this.makeTimeString(this.player.getCurrentTrackLength());
				}
				playTimeContainer.innerHTML = pt;
				divider.innerHTML = dv;
				trackLength.innerHTML = tl;
			}
			catch (ex) {}
		}
		this.updateVolumeSlider();
		this.updatePlayButton();
		this.update.defer(this.updateTimerDelay,this);
	},
	
	updateVolumeSlider:function(){
		var newValue = this.player.getVolume();
		var v = this.slrVolume.getValue();
		if (v != newValue) {
			this.slrVolume.setValue(v,true);
			this.cp.set("mradio_volume",newValue);
		}
		this.slrVolume.syncThumb();
	},
	
	updatePlayButton: function() {
		var s = this.player.getPlayerStatus();
		var c = "stopped";
		var el = Ext.get("playpause-button");
		var classes = ['stopped','playing','paused'];
		if (el) {
			for (var i=0;i<classes.length;i++) {
				if (c!=classes[i]) el.removeClass(classes[i]);
			}
			el.addClass(c);
		}
	},
	
	initPlayButton: function() {
		var el;
		el = Ext.get("playpause-button");
		var onblur = function(){this.blur();}
		if (el) {
			el.addListener('click', this.playPause, this);
			el.addListener('focus', onblur);
		}
		el = Ext.get("next-button");
		if (el) {
			el.addListener('click', this.skip, this);
			el.addListener('focus', onblur);
		}
	},


	makeTimeString: function(currentTrackTime) {
		var theTime = "";
		if ( currentTrackTime > 3600 ) {
			var trackSeconds = String(currentTrackTime % 60);
			if (trackSeconds.length == 1) {
				trackSeconds = "0" + trackSeconds;
			}
			var trackMinutes = String(((currentTrackTime - trackSeconds)/60) % 60);
			if (trackMinutes.length == 1) {
				trackMinutes = "0" + trackMinutes;
			}
			var trackHours = ((currentTrackTime - trackSeconds) - (trackMinutes * 60))/3600;
			theTime = trackHours + ":" + trackMinutes + ":" + trackSeconds;
		} else {
			var trackSeconds = String(currentTrackTime % 60);
			if (trackSeconds.length == 1) {
				trackSeconds = "0" + trackSeconds;
			}
			var trackMinutes = ((currentTrackTime - trackSeconds)/60) % 60;
			theTime = trackMinutes + ":" + trackSeconds;
		}
		return theTime;
	}
});

mRadio.Ext.ContentPanel = function(config){
	this.ds = config.ds;
	// list template
	var tpl = new Ext.XTemplate(
		'<tpl for=".">',
		'<div id="c{id}" class="thumb-wrap" title="{title}">',
			'<div class="contentitem">',
				'<img src="{imgurl}" width="130"/>',
				//'<div class="title">{title}</div>',
			'</div>',
		'</div>',
		'</tpl>'
	);
	
	var formatData = function(data){
		//data.url = config.homeUrl+'?'+Ext.urlEncode({artist:data.artist});
		this.lookup["c"+data.id] = data;
		return data;
	};
	
	this.view = new Ext.DataView({
		id:'contentlist',
		store: this.ds,
		singleSelect:true,
		//autoHeight:true,
		autoWidth:true,
		autoScroll:true,
		itemSelector:'div.thumb-wrap',
		overClass:'x-view-over',
		emptyText: mRadio.resource.getString("CONTENT_NOT_FOUND"),
		loadingText: mRadio.resource.getString("LOADING_CHANNEL"),
		tpl:tpl,
		prepareData: formatData.createDelegate(this),
		listeners: {
			//'beforeselect':function(view){},
			'selectionchange':function(view,selections){
				if (selections && selections.length > 0) {
					var el = selections[0];
					var data = this.lookup[el.id];
					if (data) this.fireEvent('contentselected', this, data);
				}
			},
			scope:this
		}
	});
	Ext.apply(config,{
		layout:'fit',
		bodyStyle:'padding:2px',
		autoScroll:true,
		items:[this.view]
	});
	mRadio.Ext.ContentPanel.superclass.constructor.call(this, config);
	this.addEvents({contentselected:true});
};
Ext.extend(mRadio.Ext.ContentPanel, Ext.Panel, {
	lookup:{},
	
	updateSelection: function() {
		if (this.player.playingContentId != '') {
			var index = this.view.indexOf(this.player.playingContentId);
			if (index!=-1) this.view.select(index);
		}
	}
});

Ext.onReady(function(){
	Ext.QuickTips.init();
	
	Blz.Widget.init();
	
	// resouce
	mRadio.resource.load(_config.lang);
	//var player = new Blz.MediaPlayer.WMP();
	var player = new Blz.MediaPlayer.Lyra();
	
	var ds = new Ext.data.JsonStore({
		url: _config.baseUrl+'/mradio/channel',
		autoLoad: false,
		id:'id',
		root:'items',
		fields: ['id','title','artist','imgurl','mediaurl','shopurl',{name:'releasedat',type:'date',dateFormat:'U'}],
		baseParams: {fmt:'json'}
	});
	
	var cp = new Ext.state.CookieProvider({
		path: "/",
		expires: new Date(new Date().getTime()+(1000*60*60*24*30)), //30 days
		domain: "x-jukebox.com"
	});
	
	var ch = (_config.lang=="ja") ? 10 : 20;
	
	
	var controlPanel = new mRadio.Ext.ControlPanel({
		id:'control-panel',
		player: player,
		ds:ds,
		cp:cp,
		channel:ch,
		margins: '0 5 0 5',
		region:'north',
		height:90
	});
	var contentPanel = new mRadio.Ext.ContentPanel({
		id:'content-panel',
		player: player,
		ds:ds,
		border: false,
		margins: '5 5 5 5',
		region:'center'
	});
	
	ds.on({
		'load': {
			fn: function(source, data){
				controlPanel.doRandomPlay();
			}
		}
	})
	
	controlPanel.on({
		'playitemchanged': {
			fn: function(source, data){
				contentPanel.updateSelection();
			}
		}
	});
	contentPanel.on({
		'contentselected': {
			fn: function(source, data){
				controlPanel.doPlay(data);
			}
		}
	});
	var viewport = new Ext.Viewport({
		layout: 'border',
		items:[
			controlPanel,
			contentPanel,
			{
				contentEl:'footer',
				region:'south',
				height:24
			}
		]
	});
	
	setTimeout(function(){
		Ext.get('loading').remove();
		Ext.get('loading-mask').fadeOut({remove:true});
		controlPanel.doInitChannel();
	}, 500);
}, null, {delay: 1}); // delay for Firefox3 in windows

