var vp = {}; // namespace VideoPort
vp.v = {};

vp.v.MessageType  = {User: 0, System:  1};
vp.v.UserType     = {Normal: 0, Guest: 1, CommonChat: 2, Anonymous: 3};
vp.v.UserRole     = {Invalid: 0, General: 1, Leader: 2, Speaker: 3, Reporter: 4, Remark: 5};
vp.v.UserStatus   = {Undefined: -127, Invalid: -1, Offline: 0, Online: 1, Busy: 2, Broadcast: 3, VIPPublic: 4, MultiHost: 5};
vp.v.ConfType     = {Single: 0, Multi:   1};
vp.v.UsetRoleIcon = ["images/attendant.gif", "images/attendant.gif", "images/owner.gif", "images/podium.gif", "images/podium.gif", "images/attendant.gif"];

vp.v.ActiveXVersion = '';
vp.v.NPAPIVersion = '';

vp.v.DefaultUrl = "";
vp.v.ServerURL = "";
vp.v.IEInstaller = "";
vp.v.NPAPIInstaller = "";
vp.v.FireFoxInstaller = "";
vp.v.ApplicationType = "application/web-client-np";
vp.v.ClassID = "CLSID:647D42B5-B9B8-4068-96B0-292F985F8A51";
vp.v.ServerHost = "";
vp.v.ServerPort = "";
vp.v.Session = "";
vp.v.LoginName = "";
vp.v.Password = "";
vp.v.ConfName = "";
vp.v.ConfPassword = "";
vp.v.Conf = vp.v.ConfType.Single;
vp.v.OtherID = "";

vp.v.CallID = "";
vp.v.Width = 480;
vp.v.Height = 409;
vp.v.ChatLogHeight = 100;
vp.v.CommonChatID = "--common";

vp.v.debug = true;
vp.v.l10n = [];
vp.v.Language = "en";
vp.v.Me = "";
vp.v.Party = "";

vp._ = function(str){ 
	var text = vp.v.l10n && vp.v.l10n && vp.v.l10n[str] ? vp.v.l10n[str] : str;
	return text.replace(/\[js\/?\]/ig,"").replace(/\[([^\]]+)\]/g,"<jQuery1>");
}


/* PRIVATE EVENTS */
function OnDebugMessage(message) 
{
    vp.Debug.log(arguments); 
	jQuery(document).trigger("OnDebugMessage", [message]);
}
function OnChangeState(state, message) 
{ 
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnChangeState', [state, message]);
}
function OnChangeOtherState(iState) 
{ 
    vp.Debug.log(arguments);
    jQuery(document).trigger('OnChangeOtherState', [iState]);
}

function OnUserChangeState(sUserID, iState)
{
	vp.Debug.log(arguments);
	jQuery(document).trigger('OnUserChangeState', [sUserID, iState]);
}

function OnReceiveUserInfo(sUserID)
{
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnReceiveUserInfo', [sUserID]);
}
function OnRoleNotify(sCallID, iRole, iOldRole)
{
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnRoleNotify', [sCallID, iRole, iOldRole]);
}

/* PUBLIC EVENTS */
function OnIncommingMessage(AIsSystem, AMessageString, AUserName, aTo, AUid, AIsOnlyActivate, ADoNotShowWindow, AIsOpenByUser)
{
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnIncommingMessage', [AIsSystem, AMessageString, AUserName, aTo, AUid, AIsOnlyActivate, ADoNotShowWindow, AIsOpenByUser]);
}

function OnChatButtonClick(bStart)
{
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnChatButtonClick', [bStart]);
}

function OnChatUserClick(sCallID, bStart)
{
	vp.Debug.log(arguments);
	jQuery(document).trigger('OnChatUserClick', [sCallID, bStart]);
}

function OnIncomingQuery(sMessag, bStart)
{
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnIncomingQuery', [sMessag, bStart]);
}

function OnLoad(CanStart)
{
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnLoad', [CanStart]);
}

function OnIncomingRecordQuery(sCallID, bDefault)
{
    vp.Debug.log(arguments);
    jQuery(document).trigger('OnIncomingRecordQuery', [sCallID, bDefault]);
}

function OnConferenceJoin(sCallId, sName, iType)
{
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnConferenceJoin', [sCallId, sName, iType]);
}

function OnConferenceLeave(sCallId, sName, iType)
{
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnConferenceLeave', [sCallId, sName, iType]);
}

function OnAnswerRecordUser(AUserID, AAnswer)
{
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnAnswerRecordUser', [AUserID, AAnswer]);
}

function OnPersonChatButtonClick(AUserID, bStart)
{
    vp.Debug.log(arguments);
///OBSOLETE
}

function OnStartInstance(FirstInstance)
{
    vp.Debug.log(arguments);
	jQuery(document).trigger('OnStartInstance', [FirstInstance]);
}

function OnCustomVerbClick(sCallID)
{
	vp.Debug.log(arguments);
    jQuery(document).trigger('onCustomButtonClick', [sCallID]);
}

/*************************
*
*	WebClient Controller
*
*************************/

vp.Controller = function(settings)
{
	this.Init(settings);
	
	this.wx = new vp.Plugin();
	this.chat = new vp.Chat();
	this.panel = new vp.Panel();
	this.users_list = new vp.UsersList();
	
	this.BindEvents(settings);
}

vp.Controller.prototype.Init = function(settings)
{
	if(!settings)
		return false;

	vp.v.DefaultUrl = settings.DefaultUrl ? settings.DefaultUrl : "http://vzochat.com";
	vp.v.CommonChatID = settings.CommonChatID ? settings.CommonChatID: "--common";
	vp.v.ChatLogHeight = settings.ChatLogHeight ? settings.ChatLogHeight : 100;
	vp.v.Width = settings.Width ? settings.Width : 480;
	vp.v.Height = settings.Height ? settings.Height : 409;
	
	vp.v.ActiveXVersion = settings.ActiveXVersion ? settings.ActiveXVersion : '2,1,4,122';
	vp.v.NPAPIVersion = settings.NPAPIVersion ? settings.NPAPIVersion : '2014122';
	
	vp.v.ServerURL = settings.ServerUrl ? settings.ServerUrl : "http://share.vzochat.com";
	vp.v.ServerHost = settings.ServerHost ? settings.ServerHost : "";
	vp.v.ServerPort = settings.ServerPort ? settings.ServerPort : "";
	vp.v.Session = settings.SessionKey ? settings.SessionKey : "";
	vp.v.LoginName = settings.LoginName ? settings.LoginName : "";
	vp.v.Password = settings.Password ? settings.Password : "";
	vp.v.ConfName = settings.ConfName ? settings.ConfName : "";
	vp.v.ConfPassword = settings.ConfPassword ? settings.ConfPassword: "";
	vp.v.OtherID = settings.OtherID ? settings.OtherID : "";
	vp.v.CallID = settings.CallID ? settings.CallID : "";

	vp.v.debug = settings.Debug ? true : false;
	vp.v.Language = settings.Language ? settings.Language : "en";
	
}

vp.Controller.prototype.BindEvents = function(settings)
{	
	/* PRIVATE EVENTS */
	 //jQuery(document).bind('OnDebugMessage', {obj: this}, function(event, message){ event.data.obj.OnDebugMessage(message)} );
	 jQuery(document).bind('OnChangeState', {obj: this}, function(event, state, message){ event.data.obj.OnChangeState(state, message)} );
	 jQuery(document).bind('OnChangeOtherState', {obj: this}, function(event, iState){ event.data.obj.OnChangeOtherState(iState)} );
	 jQuery(document).bind('OnReceiveUserInfo', {obj: this}, function(event, sUserID){ event.data.obj.OnReceiveUserInfo(sUserID)} );
	 jQuery(document).bind('OnRoleNotify', {obj: this}, function(event, sCallID, iRole, iOldRole){ event.data.obj.OnRoleNotify(sCallID, iRole, iOldRole)} );
	 jQuery(document).bind('OnUserChangeState', {obj: this}, function(event, sUserID, iState){ event.data.obj.OnUserChangeState(sUserID, iState) });
	 
	/* PUBLIC EVENTS */
	 jQuery(document).bind('OnIncommingMessage', {obj: this}, function(event, AIsSystem, AMessageString, AUserName, aTo, AUid, AIsOnlyActivate, ADoNotShowWindow, AIsOpenByUser){ event.data.obj.OnIncommingMessage(AIsSystem, AMessageString, AUserName, aTo, AUid, AIsOnlyActivate, ADoNotShowWindow, AIsOpenByUser)} );
	 jQuery(document).bind('OnChatButtonClick', {obj: this}, function(event, bStart){ event.data.obj.OnChatButtonClick(bStart)} );
	 jQuery(document).bind('OnChatUserClick', {obj: this}, function(event, sCallID, bStart){ event.data.obj.OnChatUserClick(sCallID, bStart)} );
	 jQuery(document).bind('OnIncomingQuery', {obj: this}, function(event, sMessag, bStart){ event.data.obj.OnIncomingQuery(sMessag, bStart)} );
	 jQuery(document).bind('OnLoad', {obj: this}, function(event, CanStart){ event.data.obj.OnLoad(CanStart)} );
	 //jQuery(document).bind('OnIncomingRecordQuery', {obj: this}, function(event, sCallID, bDefault){ event.data.obj.OnIncomingRecordQuery(sCallID, bDefault)});
	 jQuery(document).bind('OnConferenceJoin', {obj: this}, function(event, sCallId, sName, iType){ event.data.obj.OnConferenceJoin(sCallId, sName, iType)} );
	 jQuery(document).bind('OnConferenceLeave', {obj: this}, function(event, sCallId, sName, iType){ event.data.obj.OnConferenceLeave(sCallId, sName, iType)});
	 //jQuery(document).bind('OnAnswerRecordUser', {obj: this}, function(event, AUserID, AAnswer){ event.data.obj.OnAnswerRecordUser(AUserID, AAnswer) } );
	 //jQuery(document).bind('OnPersonChatButtonClick', {obj: this}, function(event, AUserID, bStart){ event.data.obj.OnPersonChatButtonClick(AUserID, bStart)});
	 jQuery(document).bind('OnStartInstance', {obj: this}, function(event, FirstInstance){ event.data.obj.OnStartInstance(FirstInstance) } );
	 
	 jQuery(document).bind("OnTabClose", {obj: this}, function(event, id){ event.data.obj.RemoveChatItem(id);});
	 
}

vp.Controller.prototype.Run = function()
{
	this.wx.Render();
	this.chat.Render();
	this.panel.Render();
}

// EVENTS HANDLERS
vp.Controller.prototype.CheckVersion = function()
{
	if(jQuery.browser.msie)
		return;

	var npapi_ver = new Number(this.wx.get().Version);
	if (npapi_ver < new Number(vp.v.NPAPIVersion))
	{
		if (jQuery.browser.mozilla)
		    jQuery('#vp_reinstall_firefox').show();
		else
			jQuery('#vp_reinstall_npapi').show();
	}
}

vp.Controller.prototype.OnLoad = function(CanStart)
{
	jQuery("#vp_loader").hide();
}

vp.Controller.prototype.OnChatButtonClick = function(bStart)
{
	if(bStart)
	{
		this.chat.Show();
		if(vp.v.Party.callid)
		{
			this.chat.Add(new vp.ChatItem(vp.v.Party));
			this.chat.HideTabsPanel();
			this.chat.SelectItem(vp.v.Party.callid);
			if(this.chat.Count() > 1)
				this.chat.ShowTabsPanel();
		}
	}
	else
		this.chat.Hide();
}

vp.Controller.prototype.OnChatUserClick = function(sCallID, bStart)
{
	var callid = sCallID.replace("@g", "guest_");
	var user = this.users_list.GetByID(callid);
	if(!user)
		return false;

	if(!this.chat.ExistItem(callid))
		this.chat.Add(new vp.ChatItem(user));
	this.chat.Show();
	this.chat.SelectItem(callid);
}

vp.Controller.prototype.OnSendMessage = function(_msg)
{
	this.wx.sendMessage(_msg);
}

vp.Controller.prototype.OnConferenceJoin = function(sCallId, sName, iType)
{
	vp.v.Conf = vp.v.ConfType.Multi;
	var user = new vp.User({
							callid: sCallId, 
							name: sName, 
							type: vp.v.UserType.Normal, 
							role: iType,
							status: vp.v.UserStatus.Busy
						});
						
	if(!this.panel.ExistItem(user.callid))
		this.panel.Add(new vp.PanelItem(user));
	
	if(vp.v.Me.callid == user.callid)
		return ;

	this.AddUser(user);
}

vp.Controller.prototype.OnConferenceLeave = function(sCallId, sName, iType)
{
    var callid = sCallId.replace(/^@g/, 'guest_')
	this.panel.RemoveItem(callid);
	
	// write system notice to chat if it was open
	var user = this.users_list.GetByID(callid);
	if(this.chat.ExistItem(callid))
		this.chat.PrintMessage(new vp.Message({author:user, body:vp._("[js/]User has left the conference."), type:vp.v.MessageType.System}));
		
	// remove user from participant list
	//this.users_list.RemoveItem(callid);
}

vp.Controller.prototype.OnReceiveUserInfo = function(sUserID)
{
	var name = this.wx.get().GetUserInfo(sUserID, "DisplayName");
	if(!name)
		return false;
	
	callid = sUserID.replace(/@g/, "guest_");
	if (sUserID == this.wx.get().LoginID)
	{
        if(!vp.v.Me.callid) vp.v.Me = new vp.User();
		vp.v.Me.callid = callid;
		vp.v.Me.name = name;
	}
    else if (sUserID == this.wx.get().OtherID)
	{
		if(!vp.v.Party.callid) vp.v.Party = new vp.User();
        vp.v.Party.callid = callid;
		vp.v.Party.name = name;
	}
	else
	{
		var user = this.users_list.GetByID(callid);
		if(user)
			user.name = name;
	}
	this.chat.UpdateRender(this.users_list);
	this.panel.UpdateRender(this.users_list);
}

vp.Controller.prototype.OnIncommingMessage = function(AIsSystem, AMessageString, AUserName, aTo, AUid, AIsOnlyActivate, ADoNotShowWindow, AIsOpenByUser)
{
	var callid = AUid.replace("@g", "guest_");
	var user = new vp.User();

	user = this.users_list.GetByID(callid);
	if(user)
	{}
	else if(vp.v.Party.callid == callid)
		user = vp.v.Party;
	else
	{
		user = new vp.User({callid: callid, name: AUserName});
		this.AddUser(user);
	}

	callid = aTo && !/^\s*$/.test(aTo) ? AUid : vp.v.CommonChatID;
	var msg = new vp.Message({
							author: new vp.User({callid: callid, name: user.name, status: user.status}),
							to: aTo,
							body: AMessageString,
							type: AIsSystem > 0 ? vp.v.MessageType.System : vp.v.MessageType.User
							});

	this.chat.PrintMessage(msg);
	
	if( (vp.v.Conf == vp.v.ConfType.Single || vp.v.Party.callid == callid) && this.chat.Count()<2)
		this.chat.HideTabsPanel();
	else
		this.chat.ShowTabsPanel();
		
	if(this.chat.isHide)
	{
		this.chat.Show();
		this.chat.SelectItem(msg.author.callid);
	}
}

vp.Controller.prototype.OnIncomingQuery = function(sMessag, bStart)
{
	if(!bStart)
	{
		this.wx.inMC = false;
		vp.v.Conf = vp.v.ConfType.Single;
	}
}

vp.Controller.prototype.OnDebugMessage = function(message)
{
	vp.Debug.log(arguments);
}

vp.Controller.prototype.OnChangeState = function(state, message)
{
	vp.Debug.log(arguments);
    if (message == this.wx.prevState)
		return;
	
	// set in MC flag <- always first
	this.wx.inMC = vp.v.Conf == vp.v.ConfType.Multi;
	
	if (message == 'vmConnected')
	{
		this.wx.setLanguage(vp.v.Language);
		this.CheckVersion();
		this.CheckCrash();
		
		jQuery(document).trigger('onLogin');
        jQuery(document).trigger('onConnected');
	}
    else if (message == 'vmNormal')
    {
		vp.v.Me.status = vp.v.UserStatus.Online;
		
		var otherID = this.wx.get().OtherID;
		if(otherID)
		{
			vp.v.Party = new vp.User({callid:otherID, name:otherID});
			this.wx.requestUserInfo(otherID);
		}

		if(this.wx.prevState != "vmClose")
		{
			jQuery(document).trigger('onReady', [this.wx.get().LoginID]);
			jQuery(document).trigger('onVzoWxUserDetected', [this.wx.get().LoginID]);
		}
		
		jQuery(document).trigger('onUserDetected');
        // Get Trial info
        jQuery(document).trigger('onTrialCheck', [this.wx.get().GetUserInfo(this.wx.get().LoginID, "trial") == "trial"]);
    }
    else if (message == 'vmInConference')
    {
		if(this.wx.inMC)
		{
			// add common chat and select it
			this.chat.CreateDefaultChat();
			this.panel.Show();
		}
		else
		{
			var otherID = String(this.wx.get().OtherID).replace("'", "");
			if (!otherID)
	            vp.v.Party = new vp.User({callid:"", name:"", type:vp.v.UserType.Anonymous});
			else
			{
				vp.v.Party = new vp.User({callid:otherID, name:otherID});
				this.wx.requestUserInfo(otherID);
			}
			
			otherID = otherID.replace("@g", "guest_");
			this.chat.Add(new vp.ChatItem({callid:otherID, name:otherID}));
			this.chat.SelectItem(otherID);
			if(this.chat.Count() < 2)
				this.chat.HideTabsPanel();
		}
        jQuery(document).trigger('onJoin');
    }
    else if (message == 'vmClose')
    {
        jQuery(document).trigger('onHangUp', ['Unknown']);
		
		this.panel.RemoveAll();

		this.panel.Hide();
		// disable common chat
		this.chat.DisableChat(vp.v.CommonChatID);
		// show close cross on it
		var chat_item = this.chat.GetItem(vp.v.CommonChatID);
		if(chat_item)
			chat_item.tab.btnClose.Show();
		
		//this.users_list.RemoveAll();
		//this.chat.RemoveHiddenItems();
		//this.chat.ShowTabsPanel();
		
		// teardown MC flag
		this.wx.inMC = false;
    }
	
	this.wx.prevState = message;
}

vp.Controller.prototype.OnUserChangeState = function(sUserID, iState)
{
	var callid = sUserID.replace("@g", "guest_");
	var user = this.users_list.GetByID(callid);
	if(user)
	{}
	else if(vp.v.Party.callid == callid)
		user = vp.v.Party;
	else
		return false;
		
	user.status = iState;
	this.chat.UpdateRender(this.users_list);
}

vp.Controller.prototype.OnChangeOtherState = function(iState)
{
	vp.v.Conf = iState == 5 ? vp.v.ConfType.Multi : vp.v.ConfType.Single;
	vp.v.Party.status = iState;
	this.chat.UpdateRender(this.users_list);
	jQuery(document).trigger('onCheckParty', [iState]);
}

vp.Controller.prototype.OnRoleNotify = function(sCallID, iRole, iOldRole)
{
	var callid = sCallID.replace("@g", "guest_");
	var user = this.users_list.GetByID(callid);
	if(!user)
		return false;
	
	user.role = iRole;
	this.panel.UpdateRender(this.users_list);
}

vp.Controller.prototype.OnStartInstance = function(FirstInstance)
{
	if(!FirstInstance)
		this.wx.ShowDuplicateError();
}

vp.Controller.prototype.RemoveChatItem = function(callid)
{
	var user = this.users_list.GetByID(callid);
	if(!user)
		this.chat.RemoveItem(callid);
	if(!this.users_list.Count() && !this.chat.Count())
		this.chat.Hide();
}

vp.Controller.prototype.CheckCrash = function()
{
	if(jQuery.browser.msie)
		return;
	
	vp.fun = this.wx.get;
	vp.chcr = setInterval(function(){
		if(!vp.fun().Version)
		{
			if(jQuery.browser.mozilla)
				jQuery("#vp_reinstall_firefox_on_crash").show();
			else
				jQuery("#vp_reinstall_npapi_on_crash").show();
			
			clearInterval(vp.chcr);
		}
	}, 15*1000);
}

vp.Controller.prototype.AddUser = function(_user)
{
	this.users_list.Add(_user);
	this.wx.requestUserInfo(_user.callid.replace("guest_", "@g"));
}

/* DEBUG */
vp.Debug = {};

vp.Debug.log = function log(args) {
    if (!vp.v.debug)
        return;
    if (jQuery.browser.mozilla && typeof console != "undefined")
    {
        console.log("%o: %o", args.callee, args);
    }
    else if (jQuery("#debug_log").length > 0)
    {
        //console.log(args.callee+":");
        //for (var i=0;i<args.length;i++)
        //    console.log("\t"+args[i]);
        var call = "";
        var callee = new String(args.callee);
        if (callee.match(/[^a-z]*(function.*?)\{/i))
            call = "<span style='color:#999;'>" + new String(RegExp.$1).replace('function ', '') + "</span>";
        call += ": [";
        if (args.length > 0)
        {
            for (var i=0; i<args.length; i++)
                call += '"' + args[i] + '"' + ", ";
            call = call.replace(/\,\s$/, '');
        }    
        call += "]";
        jQuery("#debug_log").prepend(call + "<br><br>");
    }
}
vp.Debug.__ = function __(msg)
{
    if (!vp.v.debug)
        return;
    if (jQuery.browser.mozilla && typeof console != "undefined")
	    console.log(msg);
    else if (jQuery("#debug_log").length > 0)
        jQuery("#debug_log").prepend("<li>" + msg + "</li>");
}
//Plugin Object
vp.Plugin = function()
{
	this.width = vp.v.Width < 480 ? vp.v.Width : 480;
	this.height = vp.v.Height < 409 ? vp.v.Height : 409;
	this.wasReconnected = false;
	this.prevState = "";
	this.inMC = false;
	
	jQuery(document).bind("OnSendMessage", {obj:this}, function(event, msg){
		event.data.obj.sendMessage(msg);
	});
	
	jQuery(document).bind("OnSoundDisable", {obj:this}, function(event){
		event.data.obj.setSoundNotifications(false);
	});
	
	jQuery(document).bind("OnSoundEnable", {obj:this}, function(event){
		event.data.obj.setSoundNotifications(true);
	});
	
	jQuery(document).bind("StartPrivateCall", {obj:this}, function(event, callID){
		event.data.obj.StartPrivateCall(callID);
	});
	
	jQuery(document).bind("AcceptCall", {obj: this}, function(event){
		event.data.obj.AcceptCall();
	});
}

vp.Plugin.prototype.CreateAXHandler = function(_name) 
{ 	
	vp.Debug.log(arguments);
    document.write("<script for='WebClientX' event='" + _name + "' language='JavaScript'>" + _name + ";</script>");
}

vp.Plugin.prototype.PreRender = function() 
{ 
	vp.Debug.log(arguments);
    // register events
    this.CreateAXHandler("OnDebugMessage(message)");
    this.CreateAXHandler("OnChangeState(state, message)");
	this.CreateAXHandler("OnUserChangeState(sUserID, iState)");
    this.CreateAXHandler("OnChangeOtherState(iState)");
    this.CreateAXHandler("OnReceiveUserInfo(sUserID)");
    this.CreateAXHandler("OnRoleNotify(sCallID, iRole, iOldRole)");
    this.CreateAXHandler("OnIncommingMessage(AIsSystem, AMessageString, AUserName, aTo, AUid, AIsOnlyActivate, ADoNotShowWindow, AIsOpenByUser)");
    this.CreateAXHandler("OnChatButtonClick(bStart)");
	this.CreateAXHandler("OnChatUserClick(sCallID, bStart)");
    this.CreateAXHandler("OnIncomingQuery(sMessag, bStart)");
    this.CreateAXHandler("OnLoad(CanStart)");
    this.CreateAXHandler("OnIncomingRecordQuery(sCallID, bDefault)");
    this.CreateAXHandler("OnConferenceJoin(sCallId, sName, iType)");
    this.CreateAXHandler("OnConferenceLeave(sCallId, sName, iType)");
    this.CreateAXHandler("OnAnswerRecordUser(AUserID, AAnswer)");
    this.CreateAXHandler("OnPersonChatButtonClick(AUserID, bStart)");
    this.CreateAXHandler("OnStartInstance(FirstInstance)");
	this.CreateAXHandler("OnCustomVerbClick(sCallID)");
    // Container
    document.write("<div id='vp'></div>");
	
	jQuery("<div id='wx_left_part'><div id='wx' ></div></div>").appendTo("#vp");
	// Wx
	jQuery("<div id='vp_activex'></div>").appendTo("#wx");
    // Loader
    jQuery("<div id='vp_loader'><h3>"+vp._("[js/]Loading VZOchat Web Client...")+"</h3><p><img src='"+vp.v.ServerURL+"/images/spinner.gif' style='margin-right:10px;'>"+vp._("[js/]Usually it takes less than 30 seconds for initial download.")+"</p><p>"+vp._("[js/]And only couple of seconds next time.")+"</p><p>"+vp._("[js/]Please wait for a while. Thank you!")+"</p></div>").appendTo("#wx");
    // Another wx instance erorr
    jQuery("<div id='vp_wx_duplicate' class='hide'><h2>"+vp._("[js/]VZOchat Application is Already Open")+"</h2><p>"+vp._("[js/]Please make sure that all instances of VZOchat webclient are closed. Thank you!")+"</p></div>").appendTo("#wx");
	// Upgrade panels
    jQuery("<div id='vp_reinstall_npapi' class='hide'><div style='position:absolute;top:10px;right:5px;'><a class='small' href='#' onclick="+'"'+"jQuery('#vp_reinstall_npapi').hide();"+'"'+"><img src='"+vp.v.ServerURL + "/images/close.gif"+"' alt='close' /></a></div><b>"+vp._("[js/]Version outdated...")+"</b><p>"+vp._("[js/]Please upgrade to a newer version:")+" <span style='font-size: larger;'><a href='"+vp.v.ServerURL+vp.v.NPAPIInstaller+"'>"+vp._("[js/]Upgrade")+"</a></span></p></div>").appendTo("#wx");
	jQuery("<div id='vp_reinstall_firefox' class='hide'><div style='position:absolute;top:10px;right:5px;'><a class='small' href='#' onclick="+'"'+"jQuery('#vp_reinstall_firefox').hide();"+'"'+"><img src='"+vp.v.ServerURL + "/images/close.gif"+"' alt='close' /></a></div><b>"+vp._("[js/]Version outdated...")+"</b><p>"+vp._("[js/]Please upgrade to a newer version:")+" <span style='font-size: larger;'><a href='"+vp.v.ServerURL+vp.v.FireFoxInstaller+"'>"+vp._("[js/]Upgrade")+"</a></span></p></div>").appendTo("#wx");
		
	// Plugin crashed
    jQuery("<div id='vp_reinstall_npapi_on_crash' class='hide'><h3 style='margin-bottom:0px;'>" + vp._("[js/]Troubleshooting") + "</h3><h4 style='margin-top:0px;'>" + vp._("[js/]Plugin has crashed or didn't started?") + "</h4><ol><li>" + vp._("[js/]Download and install the latest version:") + "</li><li style='list-style:none;'><a href='" + vp.v.ServerURL+vp.v.NPAPIInstaller + "'>" + vp.v.ServerURL+vp.v.NPAPIInstaller + "</a></li><li vlaue='2'>" + vp._("[js/]Close this browser and try one more time;") + "</li><li>" + vp._("[js/]If nothing helps please report this issue to your vendor.") + "</li></ol></div>").appendTo("#wx_left_part");
	jQuery("<div id='vp_reinstall_firefox_on_crash' class='hide'><h3 style='margin-bottom:0px;'>" + vp._("[js/]Troubleshooting") + "</h3><h4 style='margin-top:0px;'>" + vp._("[js/]Plugin has crashed or didn't started?") + "</h4><ol><li>" + vp._("[js/]Download and install the latest version:") + "</li><li style='list-style:none;'><a href='" + vp.v.ServerURL+vp.v.FireFoxInstaller + "'>" + vp.v.ServerURL+vp.v.FireFoxInstaller + "</a></li><li vlaue='2'>" + vp._("[js/]Close this browser and try one more time;") + "</li><li>" + vp._("[js/]If nothing helps please report this issue to your vendor.") + "</li></ol></div>").appendTo("#wx_left_part");
	
	// Attach debug div
    if (vp.v.debug){
        if (!jQuery.browser.mozilla || typeof console == "undefined")
            jQuery("<div style='width:450px;height:500px;color:#000;font-size:11px;overflow:scroll;' id='debug_log'></div>").appendTo("#vp");
    }
}

vp.Plugin.prototype.Render = function()
{
	this.PreRender();
	
	if (!/win/i.test(navigator.platform))
	{
		this.forNonWindows();
	} 
	else 
	{
		if (jQuery.browser.msie)
			this.ObjectForIE();
		else if (jQuery.browser.mozilla)
			this.ObjectForFireFox();
		else 
			this.ObjectForNPAPI();
	}
}

vp.Plugin.prototype.forNonWindows = function()
{
	jQuery('#vp_loader').hide();
	jQuery("<div id='vp_install_tips'><h3>"+ vp._("[js/]Not available") + "</h3><p>"+vp._("[js/]Sorry but VZOchat Web Client only works with Windows browsers only. Try to use Wine or VMWare.")+"</p></div>").appendTo("#vp_activex");
}

vp.Plugin.prototype.ObjectForFireFox = function()
{
	jQuery("<object id='WebClientX' "+
	"type='"+vp.v.ApplicationType+"' "+
	"width='" + this.width + "' "+
	"height='" + this.height + "' "+
	"LoginName='" + vp.v.LoginName + "' "+
	"LoginID='" + vp.v.LoginName + "' "+
	"Password='" + vp.v.Password + "' "+
	"Session='" + vp.v.Session + "' "+
	"StartConfType='" + vp.v.Conf + "' "+
	"ConfName='" + vp.v.ConfName + "' "+
	"ConfPassword='" + vp.v.ConfPassword + "' "+
	"Server='" + vp.v.ServerHost + "' "+
	"Port='" + vp.v.ServerPort + "' "+
	"Language='" + vp.v.Language + "' "+
	"OtherID='"	+vp.v.OtherID+"' "+
	"></object>").appendTo("#vp_activex");
	
	//jQuery("<div id='vp_install_tips'><h3>" + vp._("[js/]Install Steps") + "</h3><ol><li>" + vp._("[js/]Download an installation package with the latest version:") + "</li><li style='list-style:none;'><a href='" + vp.v.ServerURL+vp.v.FireFoxInstaller + "'>" + vp.v.ServerURL+vp.v.FireFoxInstaller + "</a></li><li value='2'>" + vp._("[js/]Close all instances of Firefox, Chrome, Opera and Safari web browsers;") + "</li><li>" + vp._("[js/]Run installer and follow the instructions.") + "</li></ol></div>").appendTo("#vp_activex object");
	jQuery("<div id='vp_install_tips'><h3>" + vp._("[js/]VZOchat Web Client for Mozilla Firefox") + "</h3><p><a href='" + vp.v.ServerURL + vp.v.FireFoxInstaller + "' onclick='jQuery(\"#vp_install_tips_ff\").show();'><img src='" + vp.v.ServerURL + "/images/addon-icn.png' border='0' alt='" + vp._("[js/]Install VZOchat Web Client") + "'/></a>&nbsp;&nbsp;&nbsp;<a href='" + vp.v.ServerURL + vp.v.FireFoxInstaller + "' style='font-size:large;' onclick='jQuery(\"#vp_install_tips_ff\").show();'>" + vp._("[js/]Install VZOchat Web Client") + "</a></p><p class='gray small'>" + vp._("[js/][b]Important:[/b] If the installation doesn&apos;t start when you click on the link above, you have to do it manually. Save the above XPI file to your local disk by right-clicking on the link and selecting Save Link As.... Then open the saved XPI file from inside Mozilla with File -> Open File... to install it. You can also drop the saved XPI file onto the Extension Manager or the Go button.") + "</p><p class='gray'>" + vp._("[js/]If plugin could not be installed, you can [:a_vzocall]connect to this user[/a] using VZOchat [:a_download]client application[/a].").replace("<:a_vzocall>", "<a href='vzochat:" + vp.v.CallID + "'>").replace("<:a_download>", "<a href='" + vp.v.DefaultURL + "/Download.aspx' target='_blank'>") + "</p></div><div id='vp_install_tips_ff' style='display:none;'><div id='vp_install_tips_ff_header'><div id='vp_install_tips_ff_left'><img src='" + vp.v.ServerURL + "/images/logo.gif' alt='VZOchat Logo'/>" + vp._("[js/]VZOchat Webclient Installation") + "<br/><span class='ff-note'>" + vp._("[js/]When yellow bar above will appear just follow the steps.") + "</span></div><div id='vp_install_tips_ff_right'><img src='" + vp.v.ServerURL + "/images/arrow.gif' alt='VZOchat Logo'/></div></div><div id='vp_install_tips_ff_details'><div id='vp_install_tips_ff_details_part'><span class='ff-number'><b>1.</b></span> " + vp._("[js/]Click [em]Allow[/em] button.") + "</div><div id='vp_install_tips_ff_details_part'><span class='ff-number'><b>2.</b></span> " + vp._("[js/]Click [em]Install Now[/em].") + "</div><div id='vp_install_tips_ff_details_part'><span class='ff-number'><b>3.</b></span> " + vp._("[js/]Restart Firefox.") + "</div></div><div id='vp_install_tips_ff_body'><a href='#' onclick='jQuery(\"#vp_install_tips_ff\").hide();' style='margin-right:5px;'>" + vp._("[js/]&#91;x&#93; close wizard") + "</a></div></div>").appendTo("#vp_activex object");
}

vp.Plugin.prototype.ObjectForNPAPI = function()
{
	jQuery("<object ID='WebClientX' border='0' "+
	"type='"+vp.v.ApplicationType+"' "+
	"width='" + this.width + "' "+
	"height='" + this.height + "' "+
	"OtherID='"+vp.v.OtherID+"' "+ 
	"LoginName='" + vp.v.LoginName + "' "+
	"LoginID='" + vp.v.LoginName + "' "+
	"Password='" + vp.v.Password + "' "+
	"Session='" + vp.v.Session + "' "+
	"StartConfType='" + vp.v.Conf + "' "+
	"ConfName='" + vp.v.ConfName + "' "+
	"ConfPassword='" + vp.v.ConfPassword + "' "+
	"Server='" + vp.v.ServerHost + "' "+
	"Port='" + vp.v.ServerPort + "' "+
	"Language='" + vp.v.Language + "' "+
	"></object>").appendTo("#vp_activex");
	
	jQuery("<div id='vp_install_tips'><h3>" + vp._("[js/]Install Steps") + "</h3><ol><li>" + vp._("[js/]Download an installation package with the latest version:") + "</li><li style='list-style:none;'><a href='" + vp.v.ServerURL+vp.v.NPAPIInstaller + "'>" + vp.v.ServerURL+vp.v.NPAPIInstaller + "</a></li><li value='2'>" + vp._("[js/]Close all instances of Firefox, Chrome, Opera and Safari web browsers;") + "</li><li>" + vp._("[js/]Run installer and follow the instructions.") + "</li></ol></div>").appendTo("#vp_activex object");
}

vp.Plugin.prototype.ObjectForIE = function()
{
	jQuery("<object id='WebClientX' align='middle' type='application/x-oleobject' "+
	"classid='" + vp.v.ClassID + "' "+
	"codebase='" + vp.v.ServerURL+vp.v.IEInstaller + "' "+
	"width='" + this.width + "' "+
	"height='" + this.height + "'"+
	">"+
	"<param name='Width' value='"+this.width+"'/>"+
	"<param name='Height' value='"+this.height+"'/>"+
	"<param name='AxBorderStyle' value='0'/>"+
	"<param name='OtherID' value='" + vp.v.OtherID + "'/>" + 
	"<param name='LoginName' value='" + vp.v.LoginName + "'/>"+
	"<param name='LoginID' value='" + vp.v.LoginName + "'/>"+
	"<param name='Password' value='" + vp.v.Password + "'/>"+
	"<param name='Session' value='" + vp.v.Session + "'/>"+
	"<param name='StartConfType' value='" + vp.v.Conf + "'/>"+
	"<param name='ConfName' value='" + vp.v.ConfName + "'/>"+
	"<param name='ConfPassword' value='" + vp.v.ConfPassword + "'/>"+
	"<param name='Server' value='" + vp.v.ServerHost + "'/>"+
	"<param name='Port' value='" + vp.v.ServerPort + "'/>"+
	"<param name='Language' value='" + vp.v.Language + "'/>" + 
	//"<div id='vp_install_tips'><h3>" + vp._("[js/]VideoPort Web Client for Internet Explorer") + "</h3><p>" + vp._("[js/]To proceed with installation please follow the on-screen instructions on the top of this window.") + "</p><p>" + vp._("[js/]If nothing happens please check that you have enabled ActiveX support in browser security settings.") + "</p></div>"+
	"</object>").appendTo("#vp_activex");
	
	//jQuery("<div id='vp_install_tips'><h3>" + vp._("[js/]VideoPort Web Client for Internet Explorer") + "</h3><p>" + vp._("[js/]To proceed with installation please follow the on-screen instructions on the top of this window.") + "</p><p>" + vp._("[js/]If nothing happens please check that you have enabled ActiveX support in browser security settings.") + "</p></div>").appendTo("#vp_activex object");
}

vp.Plugin.prototype.ShowDuplicateError = function()
{
	jQuery("#vp_wx_duplicate").show();
}

vp.Plugin.prototype.get = function() 
{ 
	return jQuery("#WebClientX")[0]; 
}

vp.Plugin.prototype.toggleChatButton = function() 
{ 
	vp.Debug.log(arguments);
    this.get().ChatButtonClick();
}

vp.Plugin.prototype.sendMessage = function(_msg) 
{ 
	vp.Debug.log(arguments);
    var type = _msg.to == vp.v.CommonChatID ? vp.v.MessageType.System : _msg.type;
    this.get().SendChatMessage(type, _msg.to.replace('guest_','@g'), _msg.body);
}

vp.Plugin.prototype.getParticipantCount = function() 
{ 
	vp.Debug.log(arguments);
    return this.get().ParticipantCount;
}

vp.Plugin.prototype.getUserRole = function(_callid) 
{ 
	vp.Debug.log(arguments);
    return this.get().GetUserRole(_callid);
}

vp.Plugin.prototype.requestUserInfo = function(_callid) 
{ 
	vp.Debug.log(arguments);
	this.get().RequestUserInfo(_callid.replace(/guest_/,'@g'));
}

vp.Plugin.prototype.setSoundNotifications = function(_state) 
{ 
	vp.Debug.log(arguments);
	this.get().SoundNotifications = _state;
}

vp.Plugin.prototype.setLanguage = function(_lang) 
{ 
	vp.Debug.log(arguments);
	if(_lang && _lang != "")
		this.get().Language = _lang;
}

vp.Plugin.prototype.StartPrivateCall = function (_call_id)
{
    this.get().Call(_call_id," ",0);
	vp.v.Conf = vp.v.ConfType.Single;
	this.inMC = false;
	vp.v.Party = new vp.User({callid:_call_id, name:_call_id});
	this.get().OtherID = _call_id;
	this.requestUserInfo(_call_id)
	
}

vp.Plugin.prototype.AcceptCall = function()
{
	this.get().AcceptCall();
}

vp.Plugin.prototype.setMCCustomImage = function setMCCustomImage(_caption, _icon_url) 
{ 
	vp.Debug.log(arguments);
    if (_icon_url.length == 0)
        return;
    this.get().SetCustomVerb(_caption, _icon_url);
}



vp.Chat = function()
{
	this.items = [];
	this.btnSound = new vp.SoundButton();
	
	this.isHide = true;
	this.isTabsPanelHide = false;
}

vp.Chat.prototype.Init = function()
{
	jQuery(document).bind("OnTabClose", {obj: this}, function(event, id){
		event.data.obj.HideItem(id);
	});
	jQuery(document).bind("OnTabSelect", {obj: this}, function(event, id){
		event.data.obj.SelectItem(id);
	});
	
	jQuery(document).bind("OnSendMessageButtonClick", {obj: this}, function(event, id){
		event.data.obj.SendMessage(id);
	});
}

vp.Chat.prototype.Render = function()
{
	this.Init();
	
	jQuery("<div id='shelf_empty'></div><div id='shelf' class='hide'><div id='tabs-empty' class='hide'></div><div id='tabs'></div><div id='chats'></div></div>").appendTo("#wx_left_part");
	
	this.btnSound.Render();
}

vp.Chat.prototype.Add = function(_chatItem)
{
	if(!_chatItem)
		return false;
	
	if(!this.ExistItem(_chatItem.id))
	{
		this.items.push(_chatItem);
		_chatItem.Render();
		if(this.Count()>1)
			this.ShowTabsPanel();
	}
	
	return _chatItem;
}

vp.Chat.prototype.CreateDefaultChat = function()
{
	if(this.ExistItem(vp.v.CommonChatID))
		return false;
		
	var user = new vp.User({
						callid: vp.v.CommonChatID, 
						name: vp._("[js/]#common"), 
						type: vp.v.UserType.CommonChat,
						role: vp.v.UserRole.General
						});
	var chatItem = new vp.ChatItem(user);
	this.Add(chatItem);
	this.SelectItem(user.callid);
	this.ShowTabsPanel();
}

vp.Chat.prototype.Show = function()
{
	jQuery("#shelf").show();
	jQuery("#shelf_empty").hide();
	this.isHide = false;
}

vp.Chat.prototype.Hide = function()
{
	jQuery("#shelf").hide();
	jQuery("#shelf_empty").show();
	this.isHide = true;
}

vp.Chat.prototype.SelectItem = function(_chatID)
{
	if( this.ExistItem(_chatID) )
	{
		for(var i in this.items)
		{
			if(typeof(this.items[i])=="function")
				continue;
			if(this.items[i].id == _chatID)
				this.items[i].Select(this.isTabsPanelHide);
			else
				this.items[i].UnSelect();
		}
	}
	else
		return false;
	
	return true;
}

vp.Chat.prototype.DisableChat = function(_chatID)
{
	var item = this.GetItem(_chatID);
	if(!item)
		return false;
	
	item.Disable();
	return true;
}

vp.Chat.prototype.RemoveItem = function(_chatID)
{
	var item = this.GetItem(_chatID);
	
	if(!item)
		return false;
	
	if(!item.isHide)
	{	
		for(var i in this.items)
		{
			if(typeof(this.items[i])=="function")
				continue;
			if(this.items[i].id != _chatID && !this.items[i].isHide && !this.items[i].isActive)
			{
				this.SelectItem(this.items[i].id);
				break;
			}
		}
	}
	
	item.Remove();
	
	// remove item from array
	var buf = [];
	while(this.items.length)
	{
		if(this.items[0].id != item.id)
			buf.push(this.items.shift());
		else
			this.items.shift();
	}
	this.items = buf;
	
	return true;
}

vp.Chat.prototype.RemoveHiddenItems = function()
{
	for(var i in this.items)
	{
		if(typeof(this.items[i])=="function")
			continue;
		if(this.items[i].isHide)
			this.RemoveItem(this.items[i].id);
	}
}

vp.Chat.prototype.HideItem = function(_chatID)
{
	var item = this.GetItem(_chatID);
	
	if(!item)
		return false;
	
	if(!item.isHide)
	{	
		for(var i in this.items)
		{
			if(typeof(this.items[i])=="function")
				continue;
			if(this.items[i].id != _chatID && !this.items[i].isHide && !this.items[i].isActive)
			{
				this.SelectItem(this.items[i].id);
				break;
			}
		}
	}
	item.Hide();
	
	return true;
}

vp.Chat.prototype.ExistItem = function(_chatID)
{
	return this.GetItem(_chatID) ? true : false;
}

vp.Chat.prototype.GetItem = function(_chatID)
{
	if(!_chatID)
		return false;
	
	for(var i in this.items)
	{
		if(typeof(this.items[i])=="function")
			continue;
		if(this.items[i].id == _chatID)
			return this.items[i];
	}
	return false;
}

vp.Chat.prototype.PrintMessage = function(_msg)
{
	if(!_msg)
		return false;
		
	var item = this.GetItem(_msg.author.callid);
	if(!item)
	{
		item = this.Add(new vp.ChatItem(_msg.author));
	}
	else if(item.isHide)
	{
		item.tab.Show();
	}

	item.PrintMessage(_msg);
	
	if(this.Count()==1)
		item.Select();
	
	return false;
}

vp.Chat.prototype.SendMessage = function(id)
{
	var item = this.GetItem(id);
	if(!item)
		return false;
		
	var msg = item.GetMessage();
	if(!msg.body)
		return false;
		
	item.PrintMessage(msg);
	item.frame.ClearInputText();
	msg.Send();
	return true;
}

vp.Chat.prototype.UpdateRender = function(_usersList)
{
	for(var i in this.items)
	{
		if(typeof(this.items[i])=="function")
			continue;
		this.items[i].tab.UpdateRender(_usersList);
		this.items[i].frame.UpdateRender(_usersList);
	}
}

vp.Chat.prototype.Count = function()
{
	return this.items.length;
}

vp.Chat.prototype.HideTabsPanel = function()
{
	jQuery("#tabs [id^=tab]").hide();
	jQuery("#vp #chats .chat .log").css({"border-color": "#ECE9D8"});
	//jQuery("#tabs-empty").show();
	this.isTabsPanelHide = true;
}

vp.Chat.prototype.ShowTabsPanel = function()
{
	this.isTabsPanelHide = false;
	jQuery("#tabs").show();
	jQuery("#tabs_empty").hide();
	jQuery("#vp #chats .chat .log").css({"border-top-color": "#FFB800"});
	for(var i in this.items)
	{
		if(typeof(this.items[i])=="function")
			continue;
		if(!this.items[i].isHide)
			jQuery("#tab_"+this.items[i].id).css({"display": "block"});
	}
	
}

vp.ChatItem = function (_user) 
{ 
    this.id = _user.callid;
    this.name = _user.name;
	
	this.user = _user;
	
	this.tab = new vp.Tab(_user);
	this.frame = new vp.Frame(_user);
	
	this.isActive = false;
	this.isHide = false;
}

vp.ChatItem.prototype.Render = function()
{
	this.tab.Render();
	this.frame.Render();
}

vp.ChatItem.prototype.Select = function(isTabsPanelHide)
{
	this.isHide = false;
	this.isActive = true;
	this.tab.Select(isTabsPanelHide);
	this.frame.Select();
}

vp.ChatItem.prototype.Remove = function()
{
	this.tab.Remove();
	delete this.tab;
	
	this.frame.Remove();
	delete this.frame;
}

vp.ChatItem.prototype.UnSelect = function()
{
	this.isActive = false;
	this.tab.Disable();
	this.frame.Hide();
}

vp.ChatItem.prototype.Hide = function()
{
	this.isHide = true;
	this.isActive = false;
	this.tab.Hide();
	this.frame.Hide();
}

vp.ChatItem.prototype.Disable = function()
{
	this.frame.Disable();
}

vp.ChatItem.prototype.PrintMessage = function(_msg)
{
	if(!_msg)
		return false;
	
	this.frame.PrintMessage(_msg);
	
	if(!this.tab.isActive())
		this.tab.Mark();
	else
		this.tab.Animate();
	
	return true;
}

vp.ChatItem.prototype.GetMessage = function()
{
	var msg = new vp.Message({author: vp.v.Me, to: this.id, type: vp.v.MessageType.User, body: this.frame.GetText()});
	return msg;
}

vp.Tab = function(_user)
{
	this.id = _user.callid;
	this.name = _user.name;
	this.status = _user.status;
	this.activity = false;
	this.isHide = false;

	this.btnClose = new vp.CloseButton(this.id);
}

vp.Tab.prototype.isCommonTab = function()
{
	return (this.id == vp.v.CommonChatID);
}

vp.Tab.prototype.Render = function()
{
	var statusImg = "";
	if(!this.isCommonTab())
		statusImg = "<div class='status'><img class='user_status_img' id='user_status_"+this.id+"' src='" + this.GetImgStatusURL() + "' alt='' /></div>";
    
	jQuery("<div class='tab' id='tab_"+this.id+"'><nobr>" + statusImg + "<div class='caption' id='caption_"+this.id+"'>"+this.name+"</div></nobr></div>").appendTo("#tabs");
	
	this.btnClose.Render();

	// bind events
    jQuery("#caption_" + this.id).bind("click", {id: this.id}, function (event){
			jQuery(document).trigger("OnTabSelect", [event.data.id]); 
		});
		
	// dont show close icon for common chat while in conf
    // and for Party chat while not in conf and another tabs are open
	if( this.isCommonTab())
		this.btnClose.Hide();
}

vp.Tab.prototype.Select = function(isTabsPanelHide)
{
	this.activity = true;
	this.isHide = false;
	jQuery("#tab_" + this.id).removeClass("tab").addClass("atab").removeClass("new");
	
	if(!isTabsPanelHide)
		this.Show();
}

vp.Tab.prototype.Disable = function()
{
	this.activity = false;
	this.isHide = false;
	jQuery("#tab_" + this.id).removeClass("atab").addClass("tab");
}

vp.Tab.prototype.Remove = function()
{
	jQuery("#tab_" + this.id).remove();
}

vp.Tab.prototype.Hide = function()
{
	this.isHide = true;
	jQuery("#tab_" + this.id).hide();
}

vp.Tab.prototype.Show = function()
{
	jQuery("#tab_" + this.id).show();
}

vp.Tab.prototype.GetImgStatusURL = function()
{
	return vp.v.ServerURL + "/images/status" + (this.status < 0 ? "no" : this.status) + ".gif";
}

vp.Tab.prototype.isActive = function()
{
	return this.activity;
}

vp.Tab.prototype.Mark = function()
{
	jQuery("#tab_"+this.id).addClass("new");
}

vp.Tab.prototype.Animate = function()
{
	jQuery("#tab_" + this.id).animate({marginLeft:'+=2px'},'fast').animate({marginLeft:'-=2px'},'fast');
}

vp.Tab.prototype.UpdateRender = function(_usersList)
{
	var user = false;
	if(_usersList && _usersList.Count())
		user = _usersList.GetByID(this.id);
	else if(this.id == vp.v.Party.callid)
		user = vp.v.Party;
	
	if(!user)
		return false;

	this.status = user.status;
	var obj = jQuery("#user_status_"+this.id);
	if(obj[0])
		obj[0].src = this.GetImgStatusURL();
	jQuery("#caption_"+this.id).text(user.name);
}

vp.Frame = function(_user)
{
	this.id = _user.callid;
	this.state = 0;
	this.submitUrl = vp.v.ServerUrl+"/images/submit-up.gif";
	this.height = vp.v.ChatLogHeight;
	
	this.btnSend = new vp.SubmitButton(this.id);
}

vp.Frame.prototype.Render = function()
{
	jQuery("<div class='chat hide' id='chat_"+this.id+"'><div class='log' id='chat_log_"+this.id+"' style='height:"+this.height+"px;'></div><div id='input'><div class='me-sign'>" + vp._("[js/]Me") + ":</div><div class='textarea' style='width:"+(vp.v.width - 65)+"px;'><textarea rows='3' cols='48' id='textarea_"+this.id+"'></textarea></div></div></div>").appendTo("#chats");
	jQuery("#chat_" + this.id + " .textarea").css({width:"415px"});
	
	// bind textarea clean up events
    jQuery("#textarea_" + this.id).keydown( function (event) { 
		if (event.which == 13) // is Enter
		{
			if (event.ctrlKey) { // is Ctrl + Enter
				event.target.value += "\x0a"; // put a newliner
				event.target.scrollTop = event.target.scrollHeight; // scroll down chat input
			} else {
				var id = event.target.id.replace('textarea_', '');
				jQuery("#submit_" + id).click();
			}
			event.preventDefault();
		}
		return event;
	} );
	
    jQuery("#textarea_" + this.id).keyup( function (event) { 
		// clean carriage return invisible chars
		if (event.target.value.replace(/[\n\t\x0a\x0d\s]+/g,'').length == 0)
			event.target.value = "";
	} );
	
	this.btnSend.Render();
}

vp.Frame.prototype.UpdateRender = function(_usersList)
{
	if(!_usersList || !_usersList.Count())
		return false;
	
	for(var i in _usersList.items)
	{
		if(typeof(_usersList.items[i])=="function")
			continue;
		var obj = jQuery("#chat_log_" + this.id);
		obj.html( obj.html().replace(_usersList.items[i].callid, _usersList.items[i].name) );
	}
}

vp.Frame.prototype.Select = function()
{
	jQuery("#chat_" + this.id).show();
	// scroll down chat log
    var obj = jQuery("#chat_log_" + this.id);
	if(obj[0])
		obj[0].scrollTop = obj[0].scrollHeight;
    // focus input
    jQuery("#textarea_" + this.id).focus();
}

vp.Frame.prototype.Hide = function()
{
	jQuery("#chat_" + this.id).hide();
}

vp.Frame.prototype.Remove = function()
{
	jQuery("#chat_" + this.id).remove();
}

vp.Frame.prototype.Disable = function()
{
	jQuery("#chat_"+this.id+" textarea").attr("disabled", "disabled");
}

vp.Frame.prototype.Enable = function()
{
	jQuery("#chat_"+this.id+" textarea").attr("disabled", false);
}

vp.Frame.prototype.PrintMessage = function(_msg)
{
    if(!_msg)
		return false;
	
	var designation = _msg.author.callid == vp.v.Me.callid ? _msg.to : _msg.author.callid;
	if (_msg.type == vp.v.MessageType.User)
    {
		var cssClass = _msg.author.callid == vp.v.Me.callid ? "me" : "party";
		var date = new Date();
		var dateStr = date.toLocaleTimeString().split(/:/)[0] + ":" + date.toLocaleTimeString().split(/:/)[1];
		var name = _msg.author.callid == vp.v.Me.callid ? vp._("[js/]Me") : _msg.author.name;
        jQuery("<p class='"+cssClass+"'><b>"+ name + "</b>:&nbsp;" + this.HTMLTrim(_msg.body) + "</p>").appendTo(jQuery("#chat_log_" + designation));
    } else if (_msg.type == vp.v.MessageType.System) {
        jQuery("<p class='system'>"+_msg.body+"</p>").appendTo(jQuery("#chat_log_" + designation));
    }
	// scroll down chat log
	jQuery("#chat_log_" + designation)[0].scrollTop = jQuery("#chat_log_" + designation)[0].scrollHeight;
}

vp.Frame.prototype.GetText = function()
{
	return jQuery("#chat_"+this.id+" textarea").val();
}

vp.Frame.prototype.ClearInputText = function()
{
	jQuery("#chat_"+this.id+" textarea").val("");
}

vp.Frame.prototype.HTMLTrim = function(str)
{
	return str ? str.replace(/(<[^>]*>)/g, "") : "";
}

vp.Panel = function(_user)
{
	this.items = [];
}

vp.Panel.prototype.Render = function()
{
	jQuery("<div id='users_container' class='hide'><h3>"+vp._("[js/]Participants")+"</h3><div id='users'></div></div>").appendTo("#vp");
}

vp.Panel.prototype.Add = function(_panelItem)
{
	if(!_panelItem)
		return false;
		
	this.items.push(_panelItem);
	_panelItem.Render();
	
	return this.items[this.items.lenght-1];
}

vp.Panel.prototype.Show = function()
{
	jQuery("#users_container").show();
}

vp.Panel.prototype.Hide = function()
{
	jQuery("#users_container").hide();
}

vp.Panel.prototype.RemoveItem = function(_id)
{
	var item = this.GetItem(_id)
	if(!item)
		return false;
		
	item.Remove();
	
	// remove item from array
	var buf = [];
	while(this.items.length)
	{
		if(this.items[0].id != item.id)
			buf.push(this.items.shift());
		else
			this.items.shift();
	}
	this.items = buf;
	
	return true;
}

vp.Panel.prototype.RemoveAll = function()
{
	for(var i in this.items)
		if(typeof(this.items[i])!="function")
			this.items[i].Remove();
			
	this.items = [];
	return true;
}

vp.Panel.prototype.GetItem = function(_id)
{
	if(!_id)
		return false;
	
	for(var i in this.items)
	{
		if(typeof(this.items[i])=="function")
			continue;
		if(this.items[i].id == _id)
			return this.items[i];
	}
	
	return false;
}

vp.Panel.prototype.ExistItem = function(id)
{
	return this.GetItem(id) ? true: false;
}

vp.Panel.prototype.UpdateRender = function(_usersList)
{
	if(!_usersList || !_usersList.Count())
		return false;
		
	for(var i in this.items)
	{
		if(typeof(this.items[i])=="function")
			continue;
		this.items[i].UpdateRender(_usersList);
	}
}

vp.PanelItem = function(_user)
{
	this.id = _user.callid;
	this.name = _user.name;
	this.status = _user.status;
	this.role = _user.role;
}

vp.PanelItem.prototype.Render = function()
{
	jQuery("<div class='user' id='panel_" + this.id + "'><div class='name'><img src='" + this.GetRoleImgURL() + "' alt='' />&nbsp;<ins>" + this.name + "</ins></div><div class='controls hide' id='controls_" + this.id + "'><div class='control' id='control_" + this.id + "_openchat'><img src='" + this.GetChatImgURL() + "' alt='' /></div><a class='control' target='_blank' href='" + vp.v.DefaultUrl + "/profile/" + this.id + "'><img src='"+vp.v.ServerURL+"/images/info.gif' alt='' /></a></div></div>").appendTo("#users");
	// controls hovering
    jQuery("#panel_" + this.id).mouseover( function (){
		jQuery(this).find(".controls").show(); 
	});
    jQuery("#panel_" + this.id).mouseout( function (){
		jQuery(this).find(".controls").hide(); 
	});
    // controls actions
    jQuery("#control_" + this.id + "_openchat").bind("click", {obj: this}, function (event){
			jQuery(document).trigger('OnChatUserClick', [event.data.obj.id, true]);
		});
    // hide chat button for self
    if (this.id == vp.v.Me.callid)
        jQuery("#control_" + this.id + "_openchat").hide();
}

vp.PanelItem.prototype.UpdateRender = function(_users_list)
{
	if(!_users_list || !_users_list.Count())
		return false;
		
	var user = _users_list.GetByID(this.id);
	if(!user)
		user = vp.v.Me;
		
	this.id = user.callid;
	this.name = user.name;
	this.status = user.status;
	this.role = user.role;
	
	jQuery("#panel_"+this.id+" .name ins").text(this.name);
	var roleImg = jQuery("#panel_"+this.id+" .name img");
	if(roleImg[0])
		roleImg[0].src = this.GetRoleImgURL();
}

vp.PanelItem.prototype.Remove = function()
{
	jQuery("#panel_" + this.id).remove();
}

vp.PanelItem.prototype.GetRoleImgURL = function()
{
	var str = vp.v.ServerURL + "/" + (vp.v.UsetRoleIcon[this.role] ? vp.v.UsetRoleIcon[this.role] : "images/attendant.gif");
	return str;
}

vp.PanelItem.prototype.GetChatImgURL = function()
{
	var str = vp.v.ServerURL+"/images/chat.gif";
	return str;
}

vp.PanelItem.prototype.GetInfoImgURL = function()
{
	var str = vp.v.ServerURL+"/images/info.gif";
	return str;
}

vp.Message = function(obj)
{
	this.author = obj && obj.author ? obj.author : new vp.User();
    this.to 	= obj && obj.to ? obj.to : "";
    this.body 	= obj && obj.body ? obj.body : "";
    this.type 	= obj && obj.type ? obj.type : 0;
}

vp.Message.prototype.Send = function()
{
	jQuery(document).trigger("OnSendMessage", [this]);
}

vp.User = function User(obj) 
{ 
    this.callid = obj && obj.callid ? obj.callid.replace(/^@g/, 'guest_') : "";
    this.name = obj && obj.name ? (/^@g/.test(obj.name) ? this.parseName(obj.name) : obj.name) : this.callid;
    this.type = obj && obj.type ? (/^@g/.test(obj.callid) ? vp.v.UserType.Guest : obj.type) : vp.v.UserType.Normal;
    this.role = obj && obj.role ? obj.role : vp.v.UserRole.Invalid;
    this.status = obj && obj.status ? obj.status : vp.v.UserStatus.Undefined;
}

vp.User.prototype.parseName = function(_name, _def)
{
	if (/^@g.*$/i.test(_name))
    {
        var name = _def == null ? vp._("[js/]Guest %id") : _def;
        if (name.length < 3)
            return name.replace('%id','');
        var id = parseInt(_name.substring(_name.length - 3), 16);
        return name.replace('%id', id);
    } else {
        return _name;
    }
}

vp.UsersList = function()
{
	this.items = [];
}

vp.UsersList.prototype.Add = function(_user)
{
	if(_user)
	{
		if(!this.GetByID(_user.callid))
			this.items.push(_user);
	}
}

vp.UsersList.prototype.GetByID = function(_callid)
{
	for(var i in this.items)
	{
		if(typeof(this.items[i])=="function")
			continue;
		if(this.items[i].callid == _callid)
			return this.items[i];
	}
	
	return false;
}

vp.UsersList.prototype.RemoveItem = function(id)
{
	if(!id)
		return false;
	
	var buf = [];
	while(this.items.length)
	{
		if(this.items[0].callid != id)
			buf.push(this.items.shift());
		else
			this.items.shift();
	}
	this.items = buf;
}

vp.UsersList.prototype.RemoveAll = function()
{
	delete this.items;
	this.items = [];
}

vp.UsersList.prototype.Count = function()
{
	return this.items.length;
}


// GUI Close Button

vp.CloseButton = function(_id)
{
	this.id = _id;
	this.imgOut = vp.v.ServerURL + "/images/cross-disabled.gif";
	this.imgOver = vp.v.ServerURL + "/images/cross.gif";
}

vp.CloseButton.prototype.Render = function()
{
	jQuery("<div id='close_"+this.id+"' class='cross'><img src='"+this.imgOut+"' alt='' /></div>").appendTo("#tab_"+this.id+" nobr");
	
	jQuery("#close_"+this.id+" > img").bind("mouseover", {obj: this }, function(event){
			event.target.src = event.data.obj.imgOver;
		});
	
	jQuery("#close_"+this.id+" > img").bind("mouseout", {obj: this}, function(event){
			event.target.src = event.data.obj.imgOut;
		});
		
	jQuery("#close_"+this.id+" > img").bind("click", { id: this.id}, function(event){
			jQuery(document).trigger("OnTabClose", [event.data.id]);
		});
}

vp.CloseButton.prototype.Show = function()
{
	jQuery("#close_" + this.id + " > img").css({visibility: "visible"});
}

vp.CloseButton.prototype.Hide = function()
{
	jQuery("#close_" + this.id + " > img").css({visibility: "hidden"});
}

vp.CloseButton.prototype.Remove = function()
{
	jQuery("#close_" + this.id).remove();
}

vp.SoundButton = function()
{
	this.status = 1;
	this.imgUrl = {
		enable: vp.v.ServerURL+"/images/sound.gif",
		disable: vp.v.ServerURL+"/images/sound_none.gif"
	};
}

vp.SoundButton.prototype.Render = function()
{
	jQuery("<div id='sound'><img src='"+this.imgUrl.enable+"' alt='"+vp._("[js/]Mute on/off sound notifications")+"' title='"+vp._("[js/]Mute on/off sound notifications")+"' /></div>").appendTo("#tabs");
	// bind events
	jQuery("#sound").bind("click", {obj: this}, function (event) {
		if(event.data.obj.status)
		{
			event.target.src = event.data.obj.imgUrl.disable;
			jQuery(document).trigger("OnSoundDisable");
			event.data.obj.status = 0;
		}
		else
		{
			event.target.src = event.data.obj.imgUrl.enable;
			jQuery(document).trigger("OnSoundEnable");
			event.data.obj.status = 1;
		}
	});
}


vp.SubmitButton = function(id)
{
	this.id = id;
	this.imgUrl = {
		up: 	vp.v.ServerURL+"/images/submit-up.gif",
		down: 	vp.v.ServerURL+"/images/submit-down.gif",
		hover: 	vp.v.ServerURL+"/images/submit-hover.gif"
	}
}

vp.SubmitButton.prototype.Render = function()
{
	jQuery("<div class='submit'><input id='submit_"+this.id+"' type='image' src='"+this.imgUrl.up+"'/></div>").appendTo("#chat_"+this.id+" #input");
	
	// bind submit action
    jQuery("#submit_" + this.id).bind("mousedown", {obj: this}, function (event) {
		event.target.src = event.data.obj.imgUrl.down;
		
		jQuery(document).bind("mouseup", {obj: event.data.obj}, function (event) {
			jQuery("#submit_" + event.data.obj.id)[0].src = event.data.obj.imgUrl.up;
			jQuery(document).unbind("mouseup");
			return false;
		});
		return false;
	});
	
	jQuery("#submit_" + this.id).bind("mouseup", {obj: this}, function (event) {
		event.target.src = event.data.obj.imgUrl.up;
		return false;
	});
	
	jQuery("#submit_" + this.id).bind("click", {obj: this}, function (event) {
		jQuery(document).trigger("OnSendMessageButtonClick", [event.data.obj.id]);
		return false;
	});
	
	// make sumbit button playable
	jQuery("#submit_" + this.id).bind("hover", {obj: this}, function (event) {
		event.target.src = event.data.obj.imgUrl.hover;
	}, function (event) {
		event.target.src = event.data.obj.imgUrl.up;
	});
	
	jQuery("#submit_" + this.id).bind("focus", {obj: this}, function (event) {
		event.target.src = event.data.obj.imgUrl.hover;
	});
	
	jQuery("#submit_" + this.id).bind("blur", {obj: this}, function (event) {
		event.target.src = event.data.obj.imgUrl.up;
	});
}

vp.v.l10n = {
'empty':''};

