var softPhone = null;

var webInterface = {
	regMessage: null,
	numberBox: null,
	callButton: null,
	adminMessage: null,
	installDiv: null,
	installLink: null,
	installText: null,

	init: function() {
		this.regMessage = $("regMessage");
		this.numberBox = $("numberBox");
		this.callButton = $("callButton");
		this.adminMessage = $("adminMessage");
		this.grantMessage = $('grantMessage');
		this.installDiv = $("installDiv");
		this.installLink = $("installLink");
		this.installText = $("installText");
		window.onbeforeunload = this.onBeforeUnload;
	},

	onBeforeUnload: function(evt) {
		var message = gettext("cancel_call_confirmation");
		evt = evt || window.event;
		if (stateManager.currentCallState == callInProgress) {
			if (evt)
				evt.returnValue = message;
			return message;
		}
	},

	drawRegState: function(state) {
		if (this.regMessage) {
			if (state.regMessageText)
				this.regMessage.innerHTML = state.regMessageText + " | ";
			else
				this.regMessage.innerHTML = "";
		}
	},

	drawCallState: function(state, url) {
		if (this.callButton)
			this.callButton.disabled = state.showCallButton ? false : true;
	},

	getVerticalBar: function() {
		return new Element('span', {'html': Browser.ie ? '&nbsp;|&nbsp;' : ' | '});
	},

	showAdminMessage: function(message, link, onclick, error) {
		if (this.adminMessage) {
			this.adminMessage.innerHTML = "";
			if (error) {
				new Element('span', {'html': error, styles: {'color': 'red'}}).inject(this.adminMessage);
				this.getVerticalBar().inject(this.adminMessage);
			}	
			if (!link) {
				new Element('span', {'html': message}).inject(this.adminMessage);
			} else {
				var link = new Element('a', {'href': link, 'html': message});
				link.onclick = onclick ? onclick : null;
				link.inject(this.adminMessage);
			}
			this.getVerticalBar().inject(this.adminMessage);
		}
	},

	clearAdminMessage: function() {
		if (this.adminMessage)
			this.adminMessage.empty();
	},
	
	showInstallDiv: function(link, onclick, text) {
		if (this.installDiv) {
			this.installDiv.style.display = 'block';

			if (this.installLink) {
				this.installLink.href = link;
				if (onclick)
					this.installLink.onclick = onclick;
			}
		}
		if (!text)
			text = gettext("browser_plugin");
		if (this.installText)
			this.installText.innerHTML = text;
	},
	
	hideInstallDiv: function() {
		if (this.installDiv) {
			this.installDiv.style.display = "none";
		}
	},

	htmlEntityEncode : function(str) {
		return str.replace(/</g,"").replace(/>/g,"");
	},
	
	setFocus: function() {
		if (this.numberBox && !this.numberBox.disabled) 
			this.numberBox.focus();
	},

	devastate: function() {
		if (this.numberBox && !this.numberBox.disabled) 
			this.numberBox.value = '';
		this.grantMessage.innerHTML = help_message;		
	},
	
	getProtocol: function(url) {
		var byat = url.split('@');
		var bycolon = byat[0].split(':');
		if (bycolon.length >= 2)
			return bycolon[0];
		else
			return null;
	},
	
	getDomain: function(url) {
		var byat = url.split('@');
		if (byat.length >= 2)
			return byat[1];
		else
			return "talkpad.ru";
	},

	getUrl: function() {
		var url = $('numberBox').value;
		url = url.replace(/[\ \-\(\)]/g,"");
		
		if (/^\s*$/.test(url))
			return null;
		if (!url.match('@'))
			url += "@talkpad.ru";
		if (!this.getProtocol(url)) {
			var protocol = "sip";
			if (jingleDomains && jingleDomains.indexOf(this.getDomain(url)) != -1)
				protocol = "jingle";
			url = protocol + ":" + url;
		}
		return url;
	},

	register: function() {
		var userid = Cookie.read('userid');
		var siteid = Cookie.read('siteid');
		if (userid && siteid)
			softPhone.register(userid, siteid);
		else {
			this.showAdminMessage(gettext("please login"));
			softPhone.unregister();
		}
	},

	unregister: function() {
		if (softPhone)
			softPhone.unregister();
	},

	makeCall: function() {
		var url = this.getUrl();
		
		if (url && this.getProtocol(url) == "jingle") {
			var jid = url.substr(7);
			var res = xmppClient.checkVoice(jid);
			if (res != 'voice') {
				// make a fake call
				onCallStateChanged('CALLING', url, '', 0, 0);
				onCallStateChanged('DISCONNCTD', url, res, 0, 0);
				if (res == 'noauth')
					xmppClient.subscribe(jid);
				return;
			}
		}
		
		if (url) {
			softPhone.call(url);
			add_entry(url);
			//this.devastate();
			Cookie.write("last_dialed", (new Date()).valueOf(), {duration: 30});
		} else {
			this.setFocus();
		}
	}
  
};

var callResults = {
	callTable: null,

	init: function() {
		this.callTable = $('callTable');
	},
	
	setDuration: function() {
		for (var i = 0; i < this.callTable.rows.length; i++) {
			var row = this.callTable.rows[i];
			if (row.getProperty('state') == 'callInProgress') {
				var extRow = $(row);
				var extRowDate = extRow.getProperty('date');
				var currentDate = (new Date()).getTime();
				var duration = currentDate - extRowDate;
				var durationHolder = row.getElements('span[name=durationHolder]')[0];
				durationHolder.innerHTML = "";

				var chargeHolder = row.getElements('span[name=chargeHolder]')[0];
				chargeHolder.innerHTML = '';

				var callUrl = extRow.getProperty('callUrl');
				if (callUrl) {
					var price = priceHash[callUrl];
				}

				var durationStr = formatTime(duration / 1000);
				if (durationStr != "")
					new Element('span', {styles: {'color': '#666666'}, 'html': "&nbsp;-&nbsp;" + durationStr}).inject(durationHolder);
				if (price && durationStr) {
					var duration_floor = Math.floor(duration / 1000);
					var charge = (price/60) * (duration_floor);
					if (balance) {
						var new_balance=balance-charge;
						display_balance(new_balance.toFixed(2));
					}
					charge = charge.toFixed(2);
					new Element('span', {styles: {'color': '#666666'}, 'html': "&nbsp;(~" + charge + " "+gettext('rur')+")"}).inject(chargeHolder);
				}
			}
		}
	},

	findRow: function(url) {
		var row;
		for (var i = 0; i < this.callTable.rows.length; i++) {
			var row = this.callTable.rows[i];
			var extRow = $(row);
			if (extRow.getProperty('callUrl') == url) {
				return row;
			}
		}
		return null;
	},

	newRow: function(call) {
		if (this.callTable.rows.length == 3) {
			row = this.callTable.deleteRow(2);
		}
		$('bbg').style.display='block';
		row = $(this.callTable.insertRow(0));
		row.setProperty('callUrl', call.url);
		var cell = row.insertCell(0);
		//row.class = 'callResult';
		return row;
	},

	makeHtml: function(call, text) {
		var urlStr = webInterface.htmlEntityEncode(call.url);
		var contact = urlStr;
		if (colored.has(contact))
			contact = colored[contact];
		else
			contact = contact.replace("sip:","");
		contact = contact.replace(/\@talkpad\.ru$/,"");
		var table = new Element('table', {'class': 'callTable'});

		var tbody = new Element('tbody').inject(table);
		var tr1 = new Element('tr').inject(tbody);
		var td1 = new Element('td',{styles: {'font-size': '1em'}}).inject(tr1);
		
		// control holder
		new Element('td', {'align':'right', styles: {'vertical-align': 'top'}, 'name': 'controlHolder'}).inject(tr1);
		var href = new Element('span', {styles: {'color': 'blue'}, 'html': contact, 'name': 'contactHolder'}).inject(td1);

		new Element('span', {styles: {'color': '#000000'}, 'name': 'stateHolder'}).inject(td1);
	   	//new Element('br').inject(td1);
		var descr = directionHash[urlStr];
		var sp = new Element('div', {styles: {'color': '#000000'}, 'name':'directionHolder'}).inject(td1);
		if (descr)
			descr.inject(sp);
		else {
			var requestData = {method: 'POST',
							   url: '/users/',
							   data: 'first=1&q='+urlStr,
							   onSuccess: function(responseJSON, responseText) {
										if (responseJSON) {
											var f = responseJSON[0];
											var h = new Hash(f);
											colored[h.num_post_n] = h.num_colorized;
											priceHash[urlStr] = h.price;
											var row = callResults.findRow(urlStr);
											descr = get_descr(h,0);
											descr.inject(row.getElements('div[name=directionHolder]')[0]);
											row.getElements('span[name=contactHolder]')[0].innerHTML = h.num_colorized;
										}
				}
			};
			requestProcessor.push(requestData);
		}

		new Element('br').inject(td1);
		var date = new Date();
		var duration = call.totalDuration != -1 ? call.totalDuration : 0;
		var time = date - duration;
		var datestr = formatDate(time);
		new Element('span', {styles: {'color': '#666666'}, 'html': gettext("begin") + ': ' + datestr}).inject(td1);
		new Element('span', {'name': 'durationHolder'}).inject(td1);
		new Element('span', {'name': 'chargeHolder'}).inject(td1);
		new Element('br').inject(td1);
		new Element('span', {styles: {'color': 'green', 'font-style': 'normal'}, 'html': urlStr}).inject(td1);
		return table;
	},

	drawControls: function(call, holder) {
		holder.innerHTML = "";
		if (call.state.showAnswerButton) {
			new Element('span', {'html': '[&nbsp;'}).inject(holder);
			var answerButton = new Element('a', {'html': gettext('answer_call'), 'href': 'javascript:softPhone.answer("' + call.url.replace(/\"/g, '\\"') + '")'}).inject(holder);
			new Element('span', {'html': '&nbsp;]&nbsp;'}).inject(holder);
		}
		if (call.state.showCancelButton) {
			new Element('span', {'html': '[&nbsp;'}).inject(holder);
			var cancelButton = new Element('a', {'html': gettext('drop_call'), 'href': 'javascript:softPhone.cancel("' + call.url.replace(/\"/g, '\\"') + '")'}).inject(holder);
			new Element('span', {'html': '&nbsp;]'}).inject(holder);
		}
		if (call.state.showAnswerButton) answerButton.focus();
		else if (call.state.showCancelButton) cancelButton.focus();
	},

	drawState: function(stateStr, holder) {
		holder.innerHTML = "";
		new Element('span', {'html': "&nbsp;-&nbsp;" + stateStr}).inject(holder);
	},

	drawCall: function(call) {
		var row = this.findRow(call.url);
		if (!row) {
			row = this.newRow(call);
			this.makeHtml(call).inject(row.cells[0]);
		}

		var stateStr = "";
		if (call.state == readyToCall) {
			if (row.getProperty('state') == 'incomingCall') {
				stateStr = gettext("lost_call");
			}
			if (row.getProperty('state') == 'callInProgress') {
				stateStr = gettext("call_ended");
				setTimeout(check_balance,1000);
			}
			if (row.getProperty('state') == 'outgoingCall') {
				if (call.info.toLowerCase().indexOf('busy') != -1)
					stateStr = gettext("busy_here");
				else if (call.info.indexOf("Unresolvable destination") == 0)
					stateStr = gettext("unresolvable_destination");
				else if (call.info == 'noauth')
					stateStr = gettext("asked_authorization");
				else if (call.info == 'novoice')
					stateStr = gettext("jingle_novoice");
				else
					stateStr = gettext("no_answer");
			}
			row.setProperty('state', 'readyToCall');
			row.setProperty('callUrl', '');
		}

		if (call.state == outgoingCall) {
			row.setProperty('state', 'outgoingCall');
			stateStr = gettext("outgoing_call")+'...';
		}

		if (call.state == incomingCall) {
			row.setProperty('state', 'incomingCall');
			stateStr = gettext("incoming_call")+"...";
		}

		if (call.state == callInProgress) {
			row.setProperty('state', 'callInProgress');
			var date = (new Date()).getTime();
			if (call.connectDurarion != -1)
				date -= Math.floor(call.connectDuration);
			row.setProperty('date', date);
			stateStr = gettext("connected");
		}

		this.drawControls(call, row.getElements('td[name=controlHolder]')[0]);
		this.drawState(stateStr, row.getElements('span[name=stateHolder]')[0]);

	}
};

function initDTMF() {
	document.addEvent('keydown', function(event) {
		if (!softPhone)
			return;
		var key = event.key;
		if ((key >= 0 && key <= 9) || key == '#' || key == '*') {
			for (var url in stateManager.calls) {
				if (!url)
					continue; // TODO: why?
				var state = stateManager.calls[url].state;
				if (state == callInProgress) {
					//alert('dial + ' + key);
					softPhone.dial(url, key);
				}
			}
		}
	});
}

function isPluginInstalled() {
	if (Browser.firefox || Browser.chrome || Browser.opera)
		return !!$('TalkPadAdapter');
	if (Browser.ie)
		return !!$('softPhoneObject').object;
	return false;
}

function createNativePhone() {
	var phone = null;
	if (Browser.firefox)
		phone = new MozillaSoftPhone();
	else if (Browser.ie)
		phone = new ActiveXSoftPhone();
	else if (Browser.chrome) {
		phone = new ChromeSoftPhone();
	} else if (Browser.opera && Browser.Platform.win) {
		phone = new OperaSoftPhone();
	}
	return phone;
}

function init() {
	var userForLogin = Cookie.read('login_panel');
	if (userForLogin) {
		Cookie.dispose('login_panel');
		loginPanel.setUser(userForLogin);
	}

	if (!registered_user)
		$('alertholder').innerHTML=gettext("register_and_install_plugin_alert");

	
	initFacebook();

	initReport();
	loadFlags();
	webInterface.init();
	callResults.init();
	initDTMF();

	var userid = Cookie.read("userid");
	var siteid = Cookie.read("siteid");

	xmppInit(userid, siteid);

	var pluginInstalled = isPluginInstalled();
	var flashDetected = swfobject.hasFlashPlayerVersion("10.1");

	softPhone = createNativePhone();

	// fallback to flash softphone
	if (!pluginInstalled && flashDetected) {
		//webInterface.showInstallDiv(softPhone.updateLink(), softPhone.installFunction(), gettext("want_better_quality"));
		softPhone = new FlashSoftPhone();
	}

	if (!softPhone) {
		webInterface.showAdminMessage(gettext("softphone_not_installed"));
		var unsupportedBrowser = function() {alert(gettext("unsupported_browser"));}
		webInterface.showInstallDiv("", unsupportedBrowser);
		return;
	}

	try {
		softPhone.init(onRegStateChanged, onCallStateChanged);
		webInterface.clearAdminMessage();
		//webInterface.hideInstallDiv();
		if (softPhone.isOutOfDate())
			webInterface.showAdminMessage(
			   gettext("update_extension") + ' ' + softPhone.latestVersion(),
			   softPhone.updateLink(), softPhone.installFunction());
	} catch (err) {
		if (err == "not_installed") {
			webInterface.showAdminMessage(gettext("softphone_not_installed"));
			webInterface.showInstallDiv(softPhone.updateLink(), softPhone.installFunction());
		} else if (userid && siteid) {
			if (/^[0-9]/.test(err))
				err = "Unknown error: " + err;
			var originalError = err;
			if (/\(/.test(err))
				err = err.split('(')[0];
			webInterface.showAdminMessage(gettext("reinstall_softphone"), softPhone.updateLink(), softPhone.installFunction(), err);
			softphone_debug(originalError);
		}
		softPhone = null;
		return;
	} 

	var compinfo = softPhone.getCompInfo();
	if (compinfo) {
		softphone_data(compinfo);
	}

	//$('alertholder').innerHTML='&nbsp;';

	stateManager.init();
	webInterface.register();
	if (!userForLogin) {
		webInterface.setFocus();
	}
	if (userid) {
		callResults.setDuration();
		setInterval("callResults.setDuration()", 500);
		if (num_to_dial) {
			$('numberBox').value = num_to_dial;
			setTimeout(function() {
				$('callButton').click();
			}, softPhone.embedded ? 1500 : 0);
		}
	}
	requestProcessor.init();
}

function initFacebook() {
	var fbFrame = document.createElement('iframe');
	fbFrame.setAttribute('src', 'http://www.facebook.com/plugins/like.php?href=http://www.facebook.com/talkpad&layout=button_count&show_faces=true&width=200&action=like&font&colorscheme=light&height=21');
	fbFrame.setAttribute('scrolling', 'no');
	fbFrame.setAttribute('frameBorder', '0');
	fbFrame.setAttribute('allowTransparency', 'true');
	fbFrame.style.border = 'none';
	fbFrame.style.overflow = 'hidden';
	fbFrame.style.width = '200px';
	fbFrame.style.height = '21px';
	$('like_id').appendChild(fbFrame);
}


function loadFlags() {
	new Asset.images(['/static/img/flags.png']);
}

var deinitialized = false;

function deinit() {
	if (deinitialized)
		return;
	deinitialized = true;
	//if (softPhone)
	//	softPhone.deinit();
	xmppDestroy();
}


