
var EmbeddedSoftPhone = new Class({
	phoneObject: null,
	embedded: true,
	lastUrl: "",

	init: function() {},
	deinit: function() {},

	getLastUrl: function() {
		return this.lastUrl;
	},

	register: function(username, siteid) {
		try {
			this.phoneObject.Register(username, siteid);
		} catch (ex) {
			// ignore
		}
	},

	unregister: function() {
		try {
			this.phoneObject.Unregister();
		} catch (ex) {
			// ignore
		}
	},

	call: function(url) {
		this.phoneObject.Call(url);
	},

	answer: function(url) {
		this.phoneObject.Answer(url);
	},

	cancel: function(url) {
		this.phoneObject.Terminate(url);
	},

	refer: function(url, urlTo) {
		this.phoneObject.Refer(url, urlTo);
	},

	dial: function(url, digits) {
		this.phoneObject.Dial(url, urlTo);
	},

	requestRegState: function() {
		this.phoneObject.GetRegState();
	},

	requestCallState: function(url) {
		this.phoneObject.GetCallState(url);
	},

	enumCalls: function() {
		var urlstr = this.phoneObject.Calls;
		if (urlstr == undefined)
			urlstr = this.phoneObject.EnumCalls();
		if (urlstr == "")
			return new Array();
		var urls = urlstr.split("|");
		return urls;
	},

	enumPlaybackDevices: function() {
		var devstr = this.phoneObject.GetPlaybackDevices();
		return devstr;
	},

	enumCaptureDevices: function() {
		var devstr = this.phoneObject.GetCaptureDevices();
		return devstr;
	},

	getVersion : function() {
		var version = this.phoneObject.Version;
		if (version == undefined)
			version = this.phoneObject.GetVersion();
		return version;
	},

	getCompInfo : function() {
		try {
			var compinfo = this.phoneObject.CompInfo;
			if (compinfo == undefined)
				compinfo = this.phoneObject.GetCompInfo();
			return compinfo;
		} catch (err) {
			return null;
		}
	},

	get : function(key) {
		try {
			var result;
			eval('result = this.phoneObject.' + key + ';');
			return result;
		} catch (err) {
			return null;
		}
	},

	set : function(key, value) {
		try {
			eval('this.phoneObject.' + key + ' = "' + value + '";');
		} catch (err) {
		}
	},

	prefetchLog : function() {},

    getLog : function() {
        try {
			var log = this.phoneObject.Log;
			if (log == undefined)
				log = this.phoneObject.GetLog();
            return log;
        } catch (err) {
            return null;
        }
    }
    
});

var ActiveXSoftPhone = new Class({
	Extends: EmbeddedSoftPhone,

	init: function() {
		this.phoneObject = $("softPhoneObject");
		if (!this.phoneObject.object)
			throw "not_installed";
		var error = "";
		try {
			var userAgent = 'TPIE' + this.getVersion();
			try {
				this.phoneObject.Init('{"user_agent": "' + userAgent + '"}');
			} catch (e) {}
		} catch (err) {
			error = this.phoneObject.Error;
			if (error == undefined) {
				try {
					error = this.phoneObject.GetError();
				} catch (e) {}
			}
			if (!error)
				error = "Unknown error";
			throw error;
		}
	},

	latestVersion: function() {
        return latestCABVersion;
    },

	isOutOfDate: function() {
		var parts = this.getVersion().split('.');
		var curParts = this.latestVersion().split('.');
		for (var i = 0; i < 4; i++) {
			if (parseInt(curParts[i]) > parseInt(parts[i]))
				return true;
		}
		return false;
	},

    updateLink: function() {
        return "/update_activex"; 
    },

    installFunction: function() { return null; }
});

var NPAPISoftPhone = new Class({
	Extends: EmbeddedSoftPhone,

	callbacks: {
		'OnRegStateChanged': null,
		'OnCallStateChanged': null
	},

	init: function(regFunc, callFunc) {
		this.callbacks.OnRegStateChanged = regFunc;
		this.callbacks.OnCallStateChanged = callFunc;
		if (!navigator.plugins["TalkPad Browser Plugin"])
			throw "not_installed";
		var error = "";
		this.phoneObject = document.embeds[0];
		try {
			this.phoneObject.SetCallback(this.callbacks);
			if (!this.phoneObject.Init())
				throw false;
		} catch (err) {
			try {
				error = this.phoneObject.GetError();
			} catch (e) {
				//error = "unknown"; TODO: uncomment later
			}
		}
		if (error)
			throw error;
	},

	latestVersion: function() {
        return latestOperaVersion;
    },
	
	isOutOfDate: function() {
		return this.getVersion() < this.latestVersion();
	},

    updateLink: function() {
        return "/softphone-" + this.latestVersion() + ".exe"; 
    },

    installFunction: function() { return null; }
});

var fader = {
	on: function() {
		var winSize = window.getSize();
		$('faderPanel').setStyles({width: winSize.x, height: winSize.y});
		$('faderPanel').fade('hide');
		$('faderPanel').setStyle('z-index', 100);
		$('faderPanel').fade(0.5);
		$('faderPanel').addEvent('click', function() {
			fader.off();
		});
	},
	off: function() {
		var fx = new Fx.Tween('faderPanel');
		fx.addEvent('complete', function() {
			$('faderPanel').setStyle('z-index', -100);
		});
		fx.start('opacity', 0.5, 0);
		console.log('started');
	}
};

// FLASH

var FlashSoftPhone = new Class({
	registrar: 'talkpad.ru',
	regFunc: null,
	callFunc: null,
	lastUrl: null,
	lastStarted: null,
	lastConnected: null,
	creationTimeout: null,
	username: '',
	password: '',
	micAllowed: false,
	
	init: function(regFunc, callFunc) {
		this.regFunc = regFunc;
		this.callFunc = callFunc;
		
		RTCKit.webPhone.onConnectStateChanged = this.onConnectState.bind(this);
		RTCKit.webPhone.onLogMessage = this.onMessage.bind(this);
		RTCKit.webPhone.onRegStateChanged = this.onRegState.bind(this);
		RTCKit.webPhone.onCallStateChanged = this.onCallState.bind(this);
		RTCKit.webPhone.onMicStateChanged = this.onMicState.bind(this);

		var params = {
			container: 	'flashPhone',
			swfDir:		'http://rtckit.com/static/swf/',
			ringback:	'/static/ringback.mp3'
		};

		//params.gateway = 'bsdpad.com:19350'

		RTCKit.webPhone.embed(params);
		RTCKit.webPhone.connect();
	},
	
	onConnectState: function(connectInfo) {
		this.connected = connectInfo.connected;
		if (!connectInfo.connected) {
			this.reregister();
		}
	},
	
	// SIP registration management

	register: function(username, password) {
		if (!RTCKit.webPhone.isConnected()) {
			clearTimeout(this.creationTimeout);
			this.creationTimeout = this.register.delay(50, this, [username, password]);
			return;
		}
		RTCKit.webPhone.register({
			registrar: this.registrar,
			username: username,
			password: 'HA1:' + password,
			publish: false,
			auth: flashAuth
		});
		this.username = username;
		this.password = password;
	},
	
	reregister: function() {
		if (this.username && this.password)
			this.register(this.username, this.password);
	},

	unregister: function() {
		try {
			RTCKit.webPhone.unregister();
		} catch (e) {}
		this.username = '';
		this.password = '';
	},
	
	onRegState: function(regInfo) {
		this.regFunc(regInfo.registered ? 'OK' : 'NONE');
		if (!regInfo.registered)
			this.onCallState({uri: this.lastUrl, state: 'IDLE', info: ''});
	},
	
	// microphone management
	
	onMicState: function(micInfo) {
		if (this.allowed != micInfo.allowed) {
			if (micInfo.allowed)
				fader.off();
		}
		this.allowed = micInfo.allowed;
	},
	
	showSettings: function() {
		RTCKit.webPhone.showSettings('privacy');
		fader.on();
		return;
	},
	
	// call management

	call: function(url) {
		var micState = RTCKit.webPhone.getMicState();
		if (micState && !micState.allowed)
			this.showSettings();
		this.lastStarted = new Date();
		this.onCallState({state: 'EARLY', uri: url, info: ''});
		RTCKit.webPhone.call({'uri': url});
	},

	answer: function(url) {
		RTCKit.webPhone.answer({'uri': url});
		this.lastConnected = new Date();
	},

	cancel: function (url) {
		RTCKit.webPhone.hangup({'uri': url});
	},

	refer: function() {
		throw 'Not implemented';
	},

	dial: function(url, digits) {
		RTCKit.webPhone.dial({'uri': url, 'digits': digits});
	},
	
	totalDuration: function() {
		return (new Date()).valueOf() - this.lastStarted.valueOf();
	},

	connectDuration: function() {
		return 0;
	},
	
	onCallState: function(callInfo) {
		this.lastUrl = callInfo.uri;
		this.lastStarted = new Date();
		var state = callInfo.state;
		switch (state) {
		case 'IDLE':
			state = 'DISCONNCTD';
			break;
		case 'OUTGOING':
			state = 'CALLING';
			break;
		case 'CONNECTED':
			state = 'CONFIRMED';
			break;
		}
		
		this.callFunc(state, callInfo.uri, callInfo.info, this.totalDuration(), this.connectDuration());
	},

	requestRegState: function() {
		return 'NONE';
	},

	requestCallState: function(url) {

	},

	enumCalls: function(url) {
		if (this.lastUrl)
			return [lastUrl];
		else
			return [];
	},
	
	getVersion: function() {
		return '0.0';
	},

	isOutOfDate: function() {
		return false;
	},
	
	getCompInfo: function() {
		return "";
	},
	
	onMessage: function(msg) {
		//console.log(msg.text);
	}
});

