///<reference path="_intellisense.js" />

/* PHONE OBJECT START */
function PhoneNumberManager()
{
	this.SortedDialCodes = null;
	this.SortedDialCodesString = null;
	
	this.Create = function( full, dc, nr )
	{
		if( dc )
		{
			dc = this.CleanNumber( dc, false );
		}

		if( null != full )
		{
			full = this.CleanNumber( full, true );
			
			if( !dc || "" == dc )
			{
				dc = this.GetDialCode( full, false );
			}
			
			if( "" != dc )
			{
				nr = full.substr( dc.length );
			}
		}
		else if( dc && !this.IsValidDialCode( dc ) )
		{
			dc = "";
		}

		if( $un != typeof( nr ) && "" != nr && "" != dc )
		{
			if( !needsTrailing0( dc, nr ) )
			{
				nr = nr.replace( /^0/, "" )
			}
			
			var ex = "-1";
			var ix = nr.indexOf( "x" );
			if( ix > -1 )
			{
				ex = nr.substr( ix + 1 );
				nr = nr.substr( 0, ix );
			}
			
			if( "" != nr )
			{
				return new TelObj( dc, nr, ex );
			}
		}
		return null;
	};
	
	this.FromSerialized = function( s )
	{
		var dc,
		nr,
		ex = "-1",
		ix_dc = s.indexOf( "-" ),
		ix_ex = s.indexOf( "x" );
		
		if( -1 < ix_dc )
		{
			dc = s.substr( 0, ix_dc );
			
			if( this.IsValidDialCode( dc ) )
			{
				if( -1 < ix_ex )
				{
					nr = s.substring( ix_dc + 1, ix_ex );
					ex = s.substr( ix_ex + 1 );
				}
				else
				{
					nr = s.substr( ix_dc + 1 );
				}
				
				if( 3 < nr.length )
				{
					return new TelObj( dc, nr, ex );
				}
			}
		}
		return null;
	};
	
	this.IsValidDialCode = function( dc )
	{
		if( null == this.SortedDialCodesString )
		{
			var l = "|";
			for( var i = 0, len = NrControlMgr.List.length; i < len; i++ )
			{
				l += NrControlMgr.List[i].DialCode + "|";
			}
			this.SortedDialCodesString = l;
		}
		return this.SortedDialCodesString.indexOf( "|" + dc + "|" ) > -1;
	};
	
	this.GetDialCode = function( nr )
	{
		if( null == this.SortedDialCodes )
		{
			this.SortedDialCodes = NrControlMgr.List.clone( true );
			this.SortedDialCodes.sort( NrControlMgr.SortByDCLength );
		}
		
		for( var i = 0, len = this.SortedDialCodes.length; i < len; i++ )
		{
			if( nr.substring( 0, String( this.SortedDialCodes[i].DialCode ).length ) == String( this.SortedDialCodes[i].DialCode ) )
			{
				return String( this.SortedDialCodes[i].DialCode );
			}
		}
		return "";
 	};
 	
 	this.CleanNumber = function( nr, ex )
 	{
 		return filterNumbers( nr, ex ).replace( /^00/, "" ).replace( /^\+/, "" ).trim();
 	};
 	
 	this.IsTelObj = function( o )
 	{
 		if( isObject( o ) )
 		{
 			return o.constructor == new TelObj().constructor;
 		}
 		return false;
 	};
 	
 	this.GetPhoneByControl = function( f )
 	{
 		var pr = this.GetPrivateData( f.Params );
 		if( null != pr )
 		{
 			return new TelObj().CreatePrivate( pr.hash, pr.type, pr.mask );
 		}
 		var nr = f.Number.value.trim();
 		if( nr.startsWith( "00" ) || nr.startsWith( "+" ) )
 		{
 			splitNumber( f );
 		}
 		return $Tel.Create( null, f.Country.value.trim(), f.Number.value.trim() );
 	};
 	
 	this.GetPrivateData = function( p )
 	{
 		if( p.isprivate )
 		{
 			return { 
 				hash : p.privatehash,
 				mask : p.privatemask,
 				type : p.privatetype
 			};
 		}
 		return null;
 	};
 	
 	this.ClearPrivateData = function( ctrl )
 	{
 		var p = ctrl.Params;
 		
 		if( p.isprivate )
 		{
 			ctrl.Number.value = ctrl.Number.value.replace( /(^[x]*)||([x]*$)/g, "" );
 		}
 		this.ClearPrivateParams( p );
 	};
 	
 	this.ClearPrivateParams = function( p )
 	{
 		if( p.isprivate )
 		{
 			p.isprivate = false;
 			delete p.privatehash;
 			delete p.privatemask;
 			delete p.privatetype;
 		}
 	};
 	
 	this.SetPrivateData = function( p, h, m, t )
 	{
 		p.isprivate = true;
 		p.privatehash = h;
 		p.privatemask = m;
 		p.privatetype = t;
 	};
}

/* TELOBJ START */
// using prototype because it has many instances... so the memory consumption is kept low
function TelObj( dc, nr, ex )
{
	this.DialCode = dc;
	this.Number = nr;
	this.Extension = ex;

	this.Type = 0;	// 0 = regular number, 1-3 = hashed home/office/mobile
	
	this.IsPrivate = false;
	this.PrivateHash = null;
	this.MaskedNumber = "";
}

TelObj.prototype = 
{
	CreateHidden : function( nr )
	{
		var tel = $Tel.FromSerialized( nr );
		if( null != tel )
		{
			this.DialCode = tel.DialCode;
			this.Number = "xxxxxxxx";
			this.Extension = "";
			
			this.IsPrivate = true;
			this.PrivateHash = tel.Serialize();
			this.Type = 4;
			this.MaskedNumber = this.DialCode + "-" + this.Number;
			
			return this;
		}
		return null;
	},

	CreatePrivate : function( hash, type, mask )
	{
		mask = mask.replace(/\+/,"");
		this.IsPrivate = true;
		this.PrivateHash = hash;
		this.Type = type;
		this.MaskedNumber = mask;
		
		var ix_dc = mask.indexOf( "-" );
		
		if( -1 < ix_dc )
		{
			var dc = mask.substr( 0, ix_dc );
			if( $Tel.IsValidDialCode( dc ) )
			{
				this.DialCode = dc;
				this.Number = mask.substr( ix_dc + 1 );
				this.Extension = "";
				
				return this;
			}
		}
		return null;
	},
		
	ToString : function( addplus )
	{
		return ( addplus ? "+" : "" ) + this.DialCode + this.Number + this.GetExtension();
	},

	Serialize : function( addprivatetype ) // addprivatetype = true just for comparing 2 hashed numbers
	{
		if( this.IsPrivate )
		{
			return this.PrivateHash + ( addprivatetype ? "|" + this.Type : "" );
		}
		return this.DialCode + "-" + this.Number + this.GetExtension();
	},

	GetExtension : function()
	{
		return "" != this.Extension && -1 < this.Extension ? "x" + this.Extension : "";
	},

	IsEqual : function( other )
	{
		if( null == other )
		{
			return false;
		}
		if( this.constructor == other.constructor )
		{
			other = other.Serialize( true );
		}
		return other == this.Serialize( true );
	},

	Encrypt : function( addplus )
	{
		if( !addplus )
		{
			addplus = false;
		}
		return CryptNumber( this.ToString( addplus ) );
	}
};
/* TELOBJ END */

/* PHONE OBJECT END */



/* PHONE INPUT MANAGER START */
function NrControlManager()
{
	this.List = [];
	this.SharedDialCodeCountryList = {};
	this.PreferredCountryList = [];

	if( $un != typeof( NrControlCountryList ) )
	{
		this.AddRange( NrControlCountryList );
	}

	this.DropDowns =
	{
		all			: null,
		source		: null,
		destination	: null
	};

	this.prefix =
	{
		Country		: 'cou_',
		DialCode	: 'dc_',
		Number		: 'num_',
		Delete		: 'DeleteLink_'
	};

	this.GenerateTemplate = function()
	{
		var root=create('div');
		root.className='nrcontrol';
		
		var _1 = create( 'div' ),
		_2 = create( 'div' ),
		_3 = create( 'div' );

		_1.className = 'countrylist';
		_2.className = 'dialcode';
		_3.className = 'number';

		root.appendChild( _1 );
		root.appendChild( _2 );
		root.appendChild( _3 );

		var dc = create( 'input' ),
		n = create( 'input' ),
		a = create( 'a' );

		_2.appendChild( dc );
		_2.appendChild( $d.createTextNode( $T( 'country' ) ) );

		_3.appendChild( n );
		_3.appendChild( $d.createTextNode( $T( 'area+phone') ) );
		_3.appendChild( a );
		a.appendChild( $d.createTextNode( $T( 'delete' ) ) );

		return root;
	};

	this.Template = this.GenerateTemplate();

	this.GetDropDown = function( type, custom )
	{
		if( null == this.DropDowns[type] )
		{
			var customlist = null;
			if( $un != typeof custom && null != custom )
			{
				customlist = [];
				for( var i = 0, len = custom.length; i < len; i++ )
				{
					customlist.push(this.GetCountry(custom[i]));
				}
			}
			this.FillDropDown( type, customlist );
		}
		var s = this.DropDowns[type];
		if( null != s )
		{
			return s.cloneNode( true );
		}
		return null;
	},

	this.CreateControl = function( name, typ, custom, nr, parent, replace, params )
	{
		if( "string" == typeof( parent ) )
		{
			parent = el( parent );
		}
		
		if( null == parent )
		{
			return;
		}
		
		if( $un == typeof( params ) || null == params )
		{
			params = {};
		}
		
		if( $un == typeof( params.showdelete ) )
		{
			params.showdelete = false;
		}
		
		var struct = this.Template.cloneNode( true );

		var type = 'custom' == typ ? typ + '_' + custom.join('_') : typ;

		struct.firstChild.appendChild( this.GetDropDown( type, custom ) );
		
		var f = this.GetFields( struct );
		f.Params = params;

		f.Country.name = f.Country.id = this.prefix.Country + name;
		f.DialCode.name = f.DialCode.id = this.prefix.DialCode + name;
		f.Number.name = f.Number.id = this.prefix.Number + name;

		f.Delete.href = '#';
		f.Delete.id = this.prefix.Delete + name;
		
		if( params.deleteclick )
		{
			AttachEvent( f.Delete, 'click', function(e){ params.deleteclick(); preventDefaultEvent( e ); return false; } );
		}
		else
		{
			AttachEvent( f.Delete, 'click', function(e){ DestMgr.Remove( f.Container ); CallMgr.CalcRate(); preventDefaultEvent( e ); return false; } );
		}
		
		if( !params.showdelete )
		{
			/* f.Delete.parentNode.removeChild(f.Delete); */
			f.Delete.style.display = "none";
		}
		
		f.DialCode.maxLength = 7;
		f.Number.maxLength = 25;
		f.DialCode.autocomplete = 'off';
		f.Number.autocomplete = 'off';
		
		var cn = "_Controls";
		f.Container[ cn ] = f.Country[ cn ] = f.DialCode[ cn ] = f.Number[ cn ] = f;

		if( f.Country.options.length < 2 )
		{
			f.Country.className = 'disabled';
			f.Country.disabled = true;
			f.DialCode.className = 'disabled';
			f.DialCode.readOnly = true;
			
			if( params.locked )
			{
				f.Number.className = 'disabled';
				f.Number.readOnly = true;
			}
		}
		else
		{
			AttachEvent( f.Country,  'change', function(){ onCountryChanged( f ); } );
			AttachEvent( f.Country,  'keyup',  function(){ onCountryChanged( f ); } );
			AttachEvent( f.Country,  'focus',  focusHandler );
			AttachEvent( f.Number,   'focus',  focusHandler );
			AttachEvent( f.DialCode, 'focus',  focusHandler );
			AttachEvent( f.DialCode, 'blur',   function(){ onDialCodeChanged( f, true, true ); } );
			
			var fnc = function(e)
			{
				return onDialCodeKeyDown( f, e );
			};
			AttachEvent( f.DialCode, 'keypress', fnc );
			AttachEvent( f.DialCode, 'keyup', fnc );
		}

		if( params.autocomplete )
		{
			PrepareTypeAhead( f.Number, { IsNrControl : true, SearchType : params.searchtype } );
			f.Number.className += ' typeahead';
		}

		AttachEvent( f.Number, 'change', function() { splitNumber( f ); } );
		AttachEvent( f.Number, 'keypress', function(e) { return onlyDigits( fixE(e), f.Number, true, true ) } );

		if( params.onchange )
		{
			var oc = function()
			{
				var f = eval( params.onchange );
				if( "function" == typeof( f ) )
				{
					f.apply( CallMgr, [] );
				}
			};
			AttachEvent( f.Country,  'change', oc );
			AttachEvent( f.DialCode, 'change', oc );
			AttachEvent( f.Number,   'change', oc );			
		}

		if( null != nr )
		{
			if( params.isprivate )
			{
				var p = $Tel.GetPrivateData( params );
				nr = new TelObj().CreatePrivate( p.hash, p.type, p.mask )
			}
			
			if( "string" == typeof( nr ) && "" != nr )
			{
				f.Number.value = nr;
				splitNumber( f );
			}
			else if( $Tel.IsTelObj( nr ) )
			{
				f.Country.value = nr.DialCode;
				f.DialCode.value = "+" + nr.DialCode;
				f.Number.value = nr.Number + nr.GetExtension();
			}
		}

		if( replace )
		{
			parent.innerHTML = '';
		}
		
		parent.appendChild( struct );
		
		return f;
	};
	
	this.GetCountry = function( dc )
	{
		var l = [ this.PreferredCountryList, this.List ];
		for( var i = 0; i < l.length; i++ )
		{
			for( var j = 0, len = l[i].length; j < len; j++ )
			{
				if( dc == l[i][j].DialCode )
				{
					return l[i][j];
				}
			}
		}
		return null;
	};

	this.GetFields = function( o )
	{
		return {
			Container	: o,
			Country		: o.firstChild.firstChild,
			DialCode	: o.childNodes[1].firstChild,
			Number		: o.childNodes[2].firstChild,
			Delete		: o.childNodes[2].childNodes[2]
		};
	};
	
	this.GetTel = function( n, f )
	{
		if( $un == typeof( f ) || !isObject( f ) )
		{
			var c = el( this.prefix.Country + n );
			if( null != c )
			{
				f = c["_Controls"];
			}
		}
		
		if( null != f )
		{
			if( f.Params )
			{
				if( f.Params.isprivate )
				{
					var p = $Tel.GetPrivateData( f.Params );
					if( null == p )
					{
						return null;
					}
					return new TelObj().CreatePrivate( p.hash, p.type, p.mask );
				}
			}
			return $Tel.Create( null, f.Country.value.trim(), f.Number.value.trim() );
		}
		return null;
	};

	this.Updated = false;
	this.UpdateCountries = function()
	{
		var clist = [];
		for( var i = 0, len = this.List.length; i < len; i++ )
		{
			if( this.List[i].SortOrder > 0 )
			{
				this.PreferredCountryList.push( this.List[i] );
			}
			
			if( clist.hasKey( '_' + this.List[i].DialCode ) )
			{
				var c2 = this.List[i], c1 = clist[ '_' + c2.DialCode ];
				this.SharedDialCodeCountryList[ '_' + c1.Id ] = c1.Name + ' & ' + c2.Name;
				this.SharedDialCodeCountryList[ '_' + c2.Id ] = c2.Name + ' & ' + c1.Name;
			}
			else
			{
				clist[ '_' + this.List[i].DialCode ] = this.List[i];
			}
		}
		this.PreferredCountryList.sort( this.SortPreferred );
		this.Updated = true;
	};

	this.SortPreferred = function( a, b )
	{
		return b.SortOrder - a.SortOrder;
	};

	this.SortByDCLength = function( a, b )
	{
		return String( b.DialCode ).length - String( a.DialCode ).length;
	};

	this.AddRange = function(arr)
	{
		for( var i = 0, len = arr.length; i < len; i++ )
		{
			var a=arr[i];
			if( a[2] > 0 )
			{
				this.Add( a[0], a[1], a[2], a[3] );
			}
		}
	};

	this.Add = function( name, id, dc, sort )
	{
		this.List.push( { Name : name, Id : id, DialCode : dc, SortOrder : sort } );
	};
	
	this.CreateDropDown = function( type, key, custom, grouping )
	{
		var s = create( "SELECT" ),
		list = custom || this.List,
		valid = this.GetValidCountryList( type, list );

		if( list.length > 1 )
		{
			s.options[0] = new Option( $T('country.choose'), '' );
		}

		if( -1 == type.indexOf( 'custom' ) )
		{
			var pre = this.PreferredCountryList;
			for( var i = 0, len = pre.length; i < len; i++ )
			{
				s.options[ s.options.length ] = new Option( grouping ? this.GetFixedName( pre[i] ) : pre[i].Name, pre[i][key] );
			}
			s.options[ s.options.length ] = new Option( '------------------------------------------------------', '' );
		}

		for( var i = 0, len = valid.length; i < len; i++ )
		{
			s.options[ s.options.length ] = new Option( grouping ? this.GetFixedName( valid[i] ) : valid[i].Name, valid[i][key] );
		}

		return s;
	};

	this.FillDropDown = function( type, custom )
	{
		this.DropDowns[ type ] = this.CreateDropDown( type, "DialCode", custom, true );
	};
	
	this.GetValidCountryList = function( type, list )
	{
		if( !this.Updated )
		{
			this.UpdateCountries();
		}
		
		if( $un == typeof( list ) )
		{
			list = this.List;
		}
		else if( type.indexOf( 'custom' ) > -1 )
		{
			return list;
		}
		
		var res = [];
		
		for( var i = 0, len = list.length; i < len; i++ )
		{
			if( 'all' == type || ( 'source' == type && !BlockedDialCodes.AsSource.contains( list[i].DialCode ) ) || ( 'destination' == type && !BlockedDialCodes.AsDestination.contains( list[i].DialCode ) ) )
			{
				res.push( list[i] );
			}
		}
		
		return res;
	};
	
	this.GetFixedName = function( c )
	{
		return this.CountryHasSharedDialCode( c.Id ) ? this.SharedDialCodeCountryList[ '_' + c.Id ] : c.Name;
	};
	
	this.CountryHasSharedDialCode = function( id )
	{
		return this.SharedDialCodeCountryList.hasKey( '_' + id );
	}
}
/* PHONE INPUT MANAGER END */



/* GENEREAL NUMBER TOOLS START */
function filterNumbers(s,ex)
{
	/* ex = allow extensions */
	if(!ex)
	{
		return s.replace( /[^+0-9]/gi, "" );
	}
	return s.replace( /[^+0-9x]/gi, "" );
}
/* GENEREAL NUMBER TOOLS END */



/* NUMBER CONTROL EVENTS START */
function onCountryChanged( ctrl ) 
{
	var c = ctrl.Country, dc = ctrl.DialCode;

	$Tel.ClearPrivateData( ctrl );

	dc.value = ( c.value != "" ? "+" : "" ) + c.value;

	if( "" == c.value && c.selectedIndex > 0 )
	{
		c.selectedIndex = 0;
	}
}
function onDialCodeChanged( ctrl, r, clean )
{
	cleardctimer();
	
	var d = ctrl.DialCode,
	c = ctrl.Country,
	s = d.value.trim().replace( /\+/g, "" ).replace( /^00/g, "" );

	$Tel.ClearPrivateData( ctrl );

	if( "" != s && setCountry( c, s ) )
	{
		if( clean )
		{
			cleanDialCode( d );
		}
		return;
	}

	c.selectedIndex = 0;
	c[0].text = ( "" == s || !r ) ? chooseC : unknownDC;
}
function onDialCodeKeyDown( ctrl, ev )
{
	cleardctimer();
	dctimer = onDialCodeChanged.delay( 100, this, ctrl, false, false );
	return onlyDigits( ev, ctrl.DialCode, true);
}
function cleardctimer()
{
	if( $un != typeof dctimer && null != dctimer )
	{
		window.clearTimeout( dctimer );
	}
	dctimer = null;
}
/* NUMBER CONTROL EVENTS END */



/* NUMBER TOOLS START */
function cleanDialCode( d )
{
	d.value = "" != d.value.trim().replace( /\+/g, "" ).replace( /^00/g , "" ) ? "+" + d.value.trim().replace( /\+/g, "" ).replace( /^00/g, "" ) : "";
}
function setCountry( o, code )
{
	o.value = code;
	return o.selectedIndex > -1 && o[ o.selectedIndex ].value == code;
}
function splitNumber( ctrl )
{
	var c = ctrl.Country,
	d = ctrl.DialCode,
	n = ctrl.Number,
	p = ctrl.Params;

	$Tel.ClearPrivateData( ctrl );
	
	n.value = filterNumbers( n.value, true ); 

	if( n.value.substring( 0, 1 ) != "+" && n.value.substring( 0, 2 ) != "00" )
	{
		return;
	}

	var num = n.value.replace( /\+/, "" ).replace( /^00/, "" );

	if( d.readOnly )
	{
		if( c.value == num.substr( 0, c.value.length ) )
		{
			n.value = num.substr( c.value.length );
			d.value = '+' + c.value;
		}
		return;
	}

	for( var i = num.length; i > 0; i-- )
	{
		if( setCountry( c, num.substr( 0, i ) ) )
		{
			n.value=num.substr(i);
			d.value="+"+c.value;
			return;
		}
	}

	d.value = "";
	c.selectedIndex = 0;
	c[0].text = chooseC;
}
function getNumber( d, n )
{
	d = el( d );
	n = el( n );
	if( null == d || null == n )
	{
		return "";
	}
	var dc = filterNumbers( d.value );
	var nr = filterNumbers( n.value );
	if( "" == dc || "" == nr )
	{
		return "";
	}
	return "+" + remTrailing0( d.value.replace( /\+/g, "" ), n.value );
}
function remTrailing0( d, n )
{
	d = d.replace( /\+/g, "" );
	if( needsTrailing0( d, n ) )
	{
		return d + n;
	}
	return d + n.replace( /^0/, "" );
}
function needsTrailing0( d, n )
{
	for( var i=0; i < specialDC.length; i++ )
	{
		if( specialDC[i] == d )
		{
			return true;
		}
	}
	if( d == 7 && n.startsWith( "095" ) )
	{
		return true;
	}
	return false
}
/* NUMBER TOOLS END */



/* NEEDS TO BE REWRITTEN START */
function focusHandler(ev)
{
	if(this.pageFocusHandler)
		this.pageFocusHandler(ev);
}
/* NEEDS TO BE REWRITTEN END */
///<reference path="_intellisense.js" />

/* TO REWRITE OR CLEANUP START */
function isPickerVisible()
{
	return $un != typeof( schedPickerClId ) && "" == el( schedPickerClId ).style.display.trim();
}
function SchedulerExists()
{
	return null != el( "scheduleBoxCallTitle" );
}
function refreshConsoleBtns()
{
	var isCall = CallMgr.IsCall(),
	isScheduled = false;
	
	if( SchedulerExists() && isFunction( isPickerVisible ) )
	{
		isScheduled = isPickerVisible();
		
		updateSubject();
		updateReminderRate( isCall );
		
		$tog( "UpperBoxLine", isScheduled );
		
		DestMgr.UpdateLinkTexts();
	}
	
	$tog( "CallBtns", isCall );
	$tog( "SMSBtns", !isCall );
	
	if( SchedulerExists() )
	{
		$tog( "ScheduledSMSBtns", isScheduled );
	}
	
	$tog( "InstantSMSBtns", !isScheduled );
}
function updateReminderRate( iscall )
{
	if( SchedulerExists() )
	{
		$tog( "callReminderRate", iscall );
		$tog( "smsReminderRate", !iscall );
	}
}
function updateSubject()
{
	if( !SchedulerExists() )
	{
		return;
	}
	
	var isSMS = CallMgr.IsSMS();

	el( "scheduleBoxCallTitle" ).style.display = isSMS ? "none" : "inline";
	el( "scheduleBoxSMSTitle" ).style.display = isSMS ? "inline" : "none";
	el( "scheduleSubjectCallTitle" ).style.display = isSMS ? "none" : "inline";
	el( "scheduleSubjectSMSTitle" ).style.display = isSMS ? "inline" : "none";

	var currValue = el( "delayedServiceSubject" ).value,
	subjectCall = el( "subjectCall" ).innerHTML,
	subjectShortMessage = el( "subjectShortMessage" ).innerHTML,
	subjectConferenceCall = el( "subjectConferenceCall" ).innerHTML;

	// update the subject only if the user didn't edit it
	if(currValue=="" || currValue==subjectCall || currValue==subjectShortMessage || currValue==subjectConferenceCall)
	{
		var value="";
		if(isSMS)
		{
			value = subjectShortMessage;
		}
		else
		{
			if (DestMgr.IsConference())
			{
				value = subjectConferenceCall;
			}
			else
			{
				value = subjectCall;
			}
		}
		el( "delayedServiceSubject" ).value = value;
	}
}
/* TO REWRITE OR CLEANUP END */



/* DESTINATION MANAGER START */
function DestinationManager()
{
	this.Container = el( "CallToContainer" );
	
	this.ClientId = 0;
	this.MAX_DESTS = 10;
	this.DestCount = 0;
	
	this.DefDC = ""; // Default Dial Code
	this.DefPA = null; // Default NrControl-Create parameters
	
	// Titles & Links that need to be changed if it's a conference call or a regular
	if( null != el( "CallToTitle" ) )
	{
		this.CTT = el( "CallToTitle" );
		this.CTTDT = this.CTT.innerHTML;				// save CallToTitle Default Text
		this.COT = el( "ConferenceToTitle" );
		this.SCS = el( "SetConferenceSpan" );
		this.APCL = el( "AddParticipantToConfLink" );
		this.APL = el( "AddParticipantLink" );
	}
	//this.ix_LastFocused = 0;
};

DestinationManager.prototype =
{
	Initialize : function()
	{
		var ctrls = this.GetAllControls();
		this.DestCount = ctrls.length;
		if( ctrls.length > 0 )
		{
			this.DefDC = ctrls[0].DialCode.value;
			this.DefPA = ctrls[0].Params.clone();
			$Tel.ClearPrivateParams( this.DefPA );
			this.UpdateDeleteLinks();
		}
	},
	
	IsConference : function()
	{
		return this.DestCount > 1;
	},
	
	// get controls
	
	GetAllControls : function()
	{
		var arr = [];
		for( var i = 0, nodes = this.Container.childNodes, len = nodes.length; i < len; i++ )
		{
			if( 1 == nodes[i].nodeType )
			{
				arr.push( nodes[i]["_Controls"] );
			}
		}
		
		return arr;
	},
	
//	GetFirstControl : function()
//	{
//		return this.GetControl( 0 );
//	},
	
//	GetLastControl : function()
//	{
//		var ctrls = this.GetAllControls();
//		return ctrls[ctrls.length-1];
//	},
	
	GetControl : function( ix )
	{
		return this.GetAllControls()[ix];
	},
	
	// set / add / remove
	
	Reset : function()
	{
		this.Clear();
		this.Add();
	},
	
	Clear : function()
	{
		var ctrls = this.GetAllControls();
		
		for( var i = ctrls.length - 1; i > -1; i-- )
		{
			this.Container.removeChild( ctrls[i].Container );
		}
		
		this.DestCount = 0;
	},
	
	SetGroup : function( nrs )
	{
		this.Clear();
		
		for( var i = 0, len = nrs.length; i < len; i++ )
		{
			this.Add( nrs[i] );
		}
		
		if( 0 == this.DestCount )
		{
			/* something went wrong, but at least: show one field */
			this.Add();
		}
	},
	
	Add : function( nr )
	{
		if( this.DestCount >= this.MAX_DESTS )
		{
			return;
		}
		
		if( $un == typeof( nr ) )
		{
			nr = this.DefDC;
		}
		
		// conference calls are only allowed to not-private numbers
		if( ( $Tel.IsTelObj( nr ) && nr.IsPrivate ) || ( this.DestCount > 0 && this.GetControl(0).Params.isprivate ) )
		{
			return;
		}
		
		var ctrl = NrControlMgr.CreateControl( "dest" + ( ++this.ClientId ), "destination", null, nr, this.Container, false, this.DefPA || { onchange : "CallMgr.CalcRate" } );
		if( null != ctrl )
		{
			foc( ctrl.Number );
			
			this.DestCount++;
			this.UpdateDeleteLinks();
			
			this.SchedulerFix();
		}
	},
	
	Remove : function( c )
	{
		this.Container.removeChild( c );
		this.DestCount--;
		if( 1 == this.DestCount )
		{
			CallMgr.Changed = true;
		}
		this.UpdateDeleteLinks();
	},
	
	// get & set phones
	
	GetDestinationPhones : function( nulls )
	{
		// if nulls is set to true the array contains also not valid phone numbers (=null); default = false
		
		var tmp = [],
		ctrls = this.GetAllControls();
		
		for( var i = 0, len = ctrls.length; i < len; i++ )
		{
			var ph = $Tel.GetPhoneByControl( ctrls[i] );
			if( null != ph || nulls )
			{
				tmp.push( ph );
			}
		}
		
		return tmp;
	},
	
	SetTel : function( tel, ix )
	{
		var ctrl = this.GetControl( ix );
		
		// conference calls are only allowed to not-private numbers
		if( this.IsConference() && tel.IsPrivate )
		{
			return;
		}
		
		ctrl.Country.value = tel.DialCode;
		ctrl.DialCode.value = "+" + tel.DialCode;
		ctrl.Number.value = tel.Number + tel.GetExtension();
		
		if( tel.IsPrivate )
		{
			$Tel.SetPrivateData( ctrl.Params, tel.PrivateHash, tel.MaskedNumber, tel.Type );
		}
		else
		{
			$Tel.ClearPrivateData( ctrl );
		}
	},
	
	// update links & titles
	
	UpdateDeleteLinks : function()
	{
		var ctrls = this.GetAllControls(),
		len = ctrls.length;
		
		for( var i = 0; i < len; i++ )
		{
			ctrls[i].Delete.style.display = len > 1 ? "" : "none";
		}
		
		this.UpdateLinkTexts();
	},
	
	UpdateLinkTexts : function()
	{
		if( null != this.CTT )
		{
			$tog( this.CTT, this.DestCount <= 1 );
			$tog( this.COT, this.DestCount > 1 );
		}
		
		var iscall = CallMgr.IsCall();
		
		if( null != this.SCS )
		{
			this.SCS.style.display = iscall && this.DestCount == 1 ? "" : "none";
			this.APCL.style.display = iscall && this.DestCount > 1 && this.DestCount < this.MAX_DESTS ? "" : "none";
		}
		
		if( null != this.APL )
		{
			this.APL.style.display = !iscall && this.DestCount < this.MAX_DESTS ? "" : "none";
		}
	},
	
	// fix for the scheduler in ie 6 (when opened and the add participant is clicked the scheduler is misplaced
	
	SchedulerFix : function()
	{
		if( SchedulerExists() && isFunction( isPickerVisible ) && isPickerVisible() )
		{
			$tog( schedPickerClId, false );
			$tog( schedPickerClId, true );
		}
	},
	
	sDN : function( t )	// set destination name
	{
		if( null != t && $un != typeof( ABMgr ) && !this.IsConference() )
		{
			if( $un == typeof( t ) )
			{
				t = this.GetDestinationPhones( true )[0];
			}
			else if( $un != typeof( t.length ) )
			{
				t = t[0];
			}
			
			var c = ABMgr.GetContactNameAndNumberType( t );
			this.CTT.innerHTML = null == c ? this.CTTDT : ( c.Name + ":" );
		}
	},
	
	HasPrivate : function() /* check if one of the destinations is private (currently we don't allow conference calls to have private destinations) */
	{
		var c = this.GetControl(0);
		return null != c && c.Params.isprivate;
	}
};

/* DESTINATION MANAGER END */



/* CALL MANAGER START */
function CallManager( name )
{
	this._instance = name;
	this.f = document.forms[0];

	this.IsLoggedIn = false;

	this.DurationIsActive = false;
	this.Duration = 0;
	this.DurationTimer = null;
	this.timer = null;
	this.rateTimer = null;
	this.hideRateTimer = null;
	this.BookmarkSMSSent = false;
	
	this.partnerMode = false;
	
	this.NoCash = false;
	this.CallId = null;
	this.CalledAt = 0;
	this.PI = 3000;
	this.API = 10000;
	this.ERR = {
		Act : "",
		Msg : ""
	};
	
	this.LFN = null;	// last from number (to see if we need to update the rate)
	this.LTN = null;	// last to number   - " -
 	this.Changed = false;
 	
 	this.DelayedServiceTime = 0;
 	this.DelayedServiceSubject = "";
 	this.DelayedRelativeType = "";
 	this.DelayedServiceSendReminder = true;
 	
 	this.ServiceTypes = {
 		SMS : "sms",
 		CALL : "call"
 	};
 	this.DelayedTypes = {
 		REL : "Relative",
 		ABS : "Absolute"
 	};
 	this.CallTypes = {
 		DEF : "",
 		SCHED : "6"
 	};
 	
 	this.CallType = "";
 	
 	this.AffiliateId = null;
 	this.AnonCallId = 0;
 	this.WebCampaignId = 0;
 	this.ID = [];
	
	this.From = null;
	this.To = [];
}

CallManager.prototype =
{
 	Init : function()
	{
		this.DurationIsActive = false;
		this.NoMoreAds = false;
		this.ClearTimer();
		this.CallId = null;
		this.CalledAt = 0;
		
		this.From = null;
		this.To = [];
	},


	// some checks


	IsSMS : function()
	{
		return isVisible( "smscontrol" );
	},


 	IsCall : function()
	{
		return !isVisible( "smscontrol" );
	},


 	IsConference : function()
	{
		return this.IsCall() && this.To.length > 1;
	},


 	IsScheduled : function()
	{
		if( $un != typeof( isPickerVisible ) )
		{
			return isPickerVisible();
		}
		return false;
	},


	// Phone Numbers


	SetFromTo : function()
 	{
 		this.From = this.GetFrom();
 		this.To = this.GetTo();
	},


	GetFrom : function()
	{
		var c = el( NrControlMgr.prefix.Country + "source" );
		if( null != c )
		{
			return NrControlMgr.GetTel( "source" );
		}
		else
		{
			var n = this.f[ "mynumber" ];
			if( n.length > 0 )
			{
				for( var i = 0; i < n.length; i++ )
				{
					if( n[i].checked )
					{
						return $Tel.Create( "+" + n[i].value );
					}
				}
			}
			else if( n.checked )
			{
				return $Tel.Create( "+" + n.value );
			}
		}
		return null;
	},


	GetTo : function( nulls ) // if nulls is set to true the array contains also not valid phone numbers (=null); default = false
	{
		return DestMgr.GetDestinationPhones( nulls );
	},


	SerializeFrom : function()
	{
		return null == this.From ? "" : this.From.Serialize();
	},


	SerializeToList : function( forcompare )
	{
		if( $un == typeof( forcompare ) )
		{
			forcompare = false;
		}
		
		var tmp = [];
		for( var i = 0, len = this.To.length; i < len; i++ )
		{
			tmp.push( this.To[i].Serialize( forcompare ) );
		}
		return tmp;
	},


	SerializeToTypeList : function()
	{
		var tmp = [];
		for( var i = 0, len = this.To.length; i < len; i++ )
		{
			tmp.push( this.To[i].Type );
		}
		return tmp;
	},


	GetToIndex : function( tel )
	{
		var to = this.GetTo( true );
		for( var i = 0, len = to.length; i < len; i++ )
		{
			if( null != to[i] && to[i].IsEqual( tel ) )
			{
				return i;
			}
		}
		return -1;
	},


	ContainsTo : function( nr )
	{
		var ph = $Tel.Create( nr );
		if( null != ph )
		{
			return( -1 != GetToIndex( ph ) );
		}
		return false;
	},


	ArePhonesValid : function()
	{
		return null != this.From && this.To.length > 0;
	},


	HasTelephonesChanged : function()
	{
		var from = null == this.From ? "" : this.From.Serialize();
		var to_list = this.SerializeToList( true ).join( "," );

		if( this.LFN != from || this.LTN != to_list || this.Changed )
		{
			this.LFN = from;
			this.LTN = to_list;
			return true;
		}
		return false;
	},


	InvalidateLastTelephones : function()
	{
		if( isVisible( "smspriceinfo" ) )
		{
			el( "smspriceinfo" ).innerHTML = "";
		}
		else if( isVisible( "priceinfo" ) )
		{
			el( "priceinfo" ).innerHTML = "";
		}
		this.LFN = null;
		this.LTN = null;
	},


	// SELECT CONTACT


	SelectContact : function( tel, ix )
	{
		if( GroupMgr && GroupMgr.AppendABEntry( tel, ix ) )
		{
			return;
		}
		
		if( "string" == typeof( tel ) )
		{
			tel = $Tel.Create( tel );
		}
		
		if( null == tel )
		{
			return;
		}
		
		var t_ix = this.GetToIndex( tel );
		
		if( -1 != t_ix )
		{
			// already existing phone number
			DestMgr.GetAllControls()[ t_ix ].Number.focus();
		}
//		else if( -1 != DestMgr.ix_LastFocus )
//		{
//			// already existing phone number
//			DestMgr.GetAllControls()[ DestMgr.ix_LastFocus ].Number.focus();
//		}
		else
		{
			// update first empty control
			var ctrls = DestMgr.GetAllControls();
			for( var i = 0, len = ctrls.length; i < len; i++ )
			{
				if( i == len - 1 || "" == ctrls[i].Number.value.trim() )
				{
					DestMgr.SetTel( tel, i );
					break;
				}
			}
		}
		
		this.CalcRate();
	},


	// Call


	Call : function()
	{
		this.Init();
		this.SetFromTo();

		if( $un != typeof( RedialManager ) && !RedialManager.saveNewCall( this ) || !this.To.length)
		{
			// redial functionality: call-to field was empty and was filled now with the last dialed number
			this.ClearDisabled();
			return;
		}

		$msg( $T( "call.init" ), "info", true, null, "infobox" );

		$X.Post( $X.Url.Call, "Call",
		{
			src : this.SerializeFrom(),
			dest : this.SerializeToList(),
			desttype : this.SerializeToTypeList(),
			timeout : this.IsLoggedIn,
			anonymousid : this.AnonCallId,
			aff : this.AffiliateId,
			conf : this.IsConference(),
			con : this.GetDestContactInfo()
		}, this.DoCall.link( this ) ).Send();
	},


	GetDestContactInfo : function()
	{
		if( ABMgr && ABMgr.GetContactNameAndNumberType && !this.IsConference() && 0 < this.To.length )
		{
			var c = ABMgr.GetContactNameAndNumberType( this.To[0] );
			if( null != c )
			{
				return c.ContactId + "," + c.typeInt + "," + c.Name.replace( /,/g, " " );
			}
		}
		return "";
	},


 	DoCall : function( re, ok )
 	{
		$show( "quickDialDiv" );
		this.ClearDisabled();
		this.PrivateCall = false;
		
		if( !ok || null == re )
		{
			return;
		}
		
		if( $un != typeof( re.interstitial ) )
		{
			if( $un != typeof( this.NNPH ) && $un != typeof( this.NCPH ) )
			{
				el( this.NNPH ).innerHTML = re.interstitial;
				Notify( true, this.NCPH, this.NNPH );
			}
		}
		else
		{
			// PartnerCallWindowDisplay();
			if( re.Error )
			{
				// PostCallPartnersRules(re.ErrorCode);
				// if(DisplayMessagePartnersRules(res.value)){ return; }

				setText( "infobox", re.Box.InfoBody );

				if( "" != re.Box.Help )
				{
					setText( "bottomhelp", re.Box.Help );
				}
			}
			else
			{
				/*
				if( $un != this.ID[ "ExpireInfo" ] && null != el( this.ID[ "ExpireInfo" ] ) )
				{
					$hide( this.ID["ExpireInfo"] );
				}
				*/
				
				if( re.PI > 0 )
				{
					this.PI = re.PI;
				}
				if( re.ActivePI > 0 )
				{
					this.API = re.ActivePI;
				}

				this.HandleResponse( re );

				this.ERR.Act = re.CallAcitvated;
				this.ERR.Msg = re.ManualCompleteText;

				if( this.PI > 0 )
				{
					this.timer = this.CheckStatus.delay( this.PI, this );
				}
			}
		}
	},


	// SCHEDULING


 	SetDelayedService : function( editFlag )
	{
		this.Init();
		this.SetFromTo();

		var currDate = new Date(),
		stype;
		
		setSchedulingData( this );
		
		this.DelayedServiceSendReminder = ( el( "delayedServiceReminder" ).checked && isParentVisible( "delayedServiceReminder" ) );

		if( this.IsSMS() )
		{
			stype = this.ServiceTypes.SMS;
			$msg( $T( "wait.scheduling.sms" ), "info", true, null, "infobox" );
		}
		else
		{
			stype = this.ServiceTypes.CALL;
			$msg( $T( "wait.scheduling.call" ), "info", true, null, "infobox" );
		}

		var editId = "-1";
		if( "editmode" == editFlag )
		{
			editId = DelayedCallListManager.editId;  
		}

		$X.Post( $X.Url.Call, "SetDelayedService",
		{
			source : this.SerializeFrom(),
			dest : this.SerializeToList(),
			destType : this.SerializeToTypeList(),
			sms : this.GetSmsMessage().trim(),
			utc : currDate.toUTCString(),
			date : this.DelayedServiceTime,
			relative : this.DelayedRelativeType,
			subject : this.DelayedServiceSubject,
			type : stype,
			reminder : this.DelayedServiceSendReminder,
			id : editId
		}, this.DoScheduledService.link( this ) ).Send();
	},


 	DoScheduledService : function( re, ok )
	{
		[ "_setcallbtn", "_setsmsbtn", "_schedsavebtn" ].each( $enable );

		if( !ok )
		{
			return;
		}
		
		if( re.Error )
		{
			setText( "infobox", re.Box.InfoBody );
		}
		else
		{
			setText( "DelayedCallsListDiv", re.Box.MainBody );
			DelayedCallListManager.getScheduledCallsList( "reload" );
			setText( "infobox", re.Box.InfoBody );
			DelayedCallListManager.editStatus = false;
			DelayedCallListManager.editId = "";
			DelayedCallListManager.ResetForm();
			showMyTab( 2 );
		}
	},


 	// CALL STATUS


 	HideStatus : function()
	{
		this.ClearTimer();
		setText( "duration", this.ERR.Act );
		setText( "infobox", this.ERR.Msg );
	},


	CheckStatus : function()
	{
		$X.Post( $X.Url.Call, "GetCallStatus",
		{
			cid : this.CallId,
			dest : this.SerializeToList(),
			desttype : this.SerializeToTypeList(),
			ticks : this.CalledAt,
			adid : this.WebCampaignId,
			conf : this.IsConference()
		}, this.DoCheckCallStatus.link( this ), false ).Send();
	},


	DoCheckCallStatus : function( re, ok )
	{
		if( !ok || null == re )
		{
			this.HideStatus();
			return;
		}

		if( re.Error )
		{
			setText( "infobox", re.Box.InfoBody );
		}
		else
		{
			this.HandleResponse( re );
			
            if( "done" == re.Status || "busy" == re.Status )
			{
				if(this.partnerMode)
				{
					document.location.reload();	
				}
			
				this.ClearTimer();
				this.NoCash = re.NoCash;

				if( $un != typeof( GroupMgr ) )
				{
					GroupMgr.AfterGroupCall( this.To );
				}

				if( re.ShowEmptyCallForm )
				{
					( function(){ redirect( "./" + ( this.NoCash ? "?rc=noca" : "" ) ); } ).delay( 1500, this );
				}
				else
				{
					foc( "newNumberName" );
				}

				foc( "invitationemail" );
			}
			else
			{
				this.timer = this.CheckStatus.delay( "active" == re.Status ? this.API : this.PI, this );
			}
		}
	},


 	ClearTimer : function()
 	{
 		window.clearTimeout( this.timer );
 		window.clearInterval( this.DurationTimer );
 		this.timer = null;
 		this.DurationTimer = null;
 	},
 
 
	// currently we don't show a call duration
	// SO DON'T DELETE THIS PARAGRAPH - MAY BE USED IN THE FUTURE
	/*
	UpdateTimer : function()
	{
		var span = this.Duration++;
		var h = Math.floor( span / 3600 );
		span -= h * 3600;
		var m = Math.floor( span / 60 );
		span -= m * 60;
		setText( "duration", this.fill0( h ) + ":" + this.fill0( m ) + ":" + this.fill0( Math.round( span ) ) + " minutes" );
	},
	fill0 : function( t )
 	{
 		t = String( t );
 		return 1 == t.length ? "0" + t : t;
 	},
	*/


	ClearDisabled : function()
	{
		[ "_callbtn", "_setcallbtn", "_smsbtn", "_setsmsbtn" ].each( $enable );	
	},


	// SMS


	GetSmsMessage : function()
	{
		SmsMgr.Update( true );
		return SmsMgr.Serialized();
	},


	SendSms : function( msg )
	{
		if( $un != typeof( RedialManager ) && !RedialManager.saveNewCall( this ) || !this.To.length)
		{
			/* If redial causes the click - don't send the sms */
			this.ClearDisabled();
			return;
		}

		$msg( msg, "info", true, null, "infobox" );

		this.Init();
		this.SetFromTo();
		
		$X.Post( $X.Url.SMS, "SendSMS",
		{
			src : this.SerializeFrom(),
			dest : this.SerializeToList(),
			desttype : this.SerializeToTypeList(),
			timeout : this.IsLoggedIn,
			sms : this.GetSmsMessage(),
			type : "0"
		}, this.DoSms.link( this ) ).Send();
	},


	DoSms : function( re, ok )
	{
		this.ClearDisabled();

		if( !ok || null == re )
		{
			return;
		}

		if( re.Error )
		{
			setText( "infobox", re.Box.InfoBody );
			if( "" != re.Box.Help )
			{
				setText( "bottomhelp", re.Box.Help );
			}
		}
		else
		{
			this.PI = re.PI;
			this.API = re.ActivePI;

			this.HandleResponse( re );

			this.ERR.Act = re.CallAcitvated;
			this.ERR.Msg = re.ManualCompleteText;

			if( this.PI > 0 )
			{
				this.timer = this.GoHome.delay( 2500, this );
			}
		}
	},
	
	
	SendDID : function( name, nr )
	{
		$X.Post( $X.Url.Call, "SendDID", { "name" : name, "nr" : nr }, null ).Send();
	},


	/* suspected not to be used at all
	SendFixedSms : function( fromSerializedTel, message, message_type, url )
 	{
 		$X.Post( $X.Url.SMS, "SendSms",
		{
			src : fromSerializedTel,
			dest : fromSerializedTel,
			timeout : false,
			sms : message,
			type : message_type,
			"url" : url
		}, this.DoFixedSms.link( this ) ).Send();
 	},
 
 
	DoFixedSms : function( re, ok )
	{
		this.ClearDisabled();
		if( !ok || null == re )
		{
			return;
		}
		
		if( re.Error )
		{
			setText( "infobox", re.Box.InfoBody );
			if( "" != re.Box.Help )
			{
				setText( "bottomhelp", re.Box.Help );
			}
		}
		else
		{
			this.PI = re.PI;
			this.API = re.ActivePI;

			this.HandleResponse( re );

			this.ERR.Act = re.CallAcitvated;
			this.ERR.Msg = re.ManualCompleteText;

			if( this.PI > 0 )
			{
				this.timer = this.GoHome.delay( 2500, this );
			}
		}
	},*/


 	HideSms : function()
	{
		$show( "CallBtns" );
		$hide( "SMSBtns" );
		$hide( "smscontrol" );
		
		setText( "infobox", "" );

		var e = el( "SmsMessageBox" );
		/*
		if( null != e )
		{
			e.value = "";
		}
		*/
		
		this.Changed = true;
		this.CalcRate();
	},


	ShowSms : function()
	{
		$hide( "CallBtns" );
		$show( "SMSBtns" );
		$show( "smscontrol" );
		setText( "infobox", "" );
		
		this.Changed = true;
		this.CalcRate();
	},


	/* suspected not to be used at all
	SendBookmarkSMS : function( title, url  )
	{
		if (!this.BookmarkSMSSent) {
			this.BookmarkSMSSent = true;
			$X.Post( $X.Url.SMS, "SendBookmarkSMS", { src : this.SerializeFrom(), to : this.SerializeToList(), "title" : title, "url" : url }, null ).Send();
		}			
	},
	*/
 
	// CALCULATE RATE


	CalcRate : function()
	{
		this.SetFromTo();
		
		if( this.HasTelephonesChanged() )
		{
			DestMgr.sDN( this.To );
			
			if( null != this.rateTimer )
			{
				window.clearTimeout( this.rateTimer );
				window.clearTimeout( this.hideRateTimer );
				
				this.rateTimer = this.hideRateTimer = null;
			}
			
			this.rateTimer = (function()
			{
				this.hideRateTimer = ( function()
				{
					$html( "priceinfo", "" );
					$html( "infobox", "" );
					$hide( "infobox", "infoboxline" );
				} ).delay( 250, this );
				
				if( isVisible( "CallBtns" ) )
				{
					this.CalcCallRate();
				}
				else if( isVisible( "SMSBtns" ) )
				{
					this.CalcSmsRate();
					SmsMgr.Update( true );
				}
			}).delay( 300, this );
		}
	},


	CalcCallRate : function()
	{
		/* avoid Ajax overhead in case of invalid telephones */
		if( !this.ArePhonesValid() )
		{
			this.InvalidateLastTelephones();
		}
		else
		{
			this.Changed = false;
			
			$X.Post( $X.Url.Call, "GetRate",
			{
				src : this.SerializeFrom(),
				dest : this.SerializeToList(),
				desttype : this.SerializeToTypeList(),
				type : this.CallType,
				schedule : this.IsScheduled()
			}, this.ShowRate.link( this ), false ).Send();
		}
	},


 	CalcSmsRate : function()
	{
		if( isVisible( "SMSBtns" ) )
		{
			if( !this.ArePhonesValid() )
			{
				this.InvalidateLastTelephones();
			}
			else
			{
				this.Changed = false;
				
				$X.Post( $X.Url.SMS, "GetRate",
				{
					src : this.SerializeFrom(),
					dest : this.SerializeToList(),
					desttype : this.SerializeToTypeList(),
					schedule : this.IsScheduled()
				}, this.ShowRate.link( this ), false ).Send();
			}
		}
	},


	ShowRate : function( res, ok )
	{
		window.clearTimeout( this.hideRateTimer );
		
		//if( null != res.error )
		if( !ok )
		{
			return;
		}
		
		//if( null != res.error || null == res.value || "" == res.value )
		if( "" == res )
		{
			el( "priceinfo" ).innerHTML = "";
			return;
		}
		
		//var re = Eval( res.value );
		var re = res;
		
		/* if(DisplayMessagePartnersRules(res.value)) { return; } */
	
		/* UDI: BUG WORKAROUND CONCERNING CALL BUTTON DISAPPEARING by avoiding display = none to 'priceinfo' element */
		if( this.IsSMS() )
		{
			if( re.rate.indexOf( "[[" ) > -1 )
			{
				SmsMgr.UpdateRate( re.rate );
			}
			else
			{
				SmsMgr.ClearRate()
			}
		}
		else
		{
			if( "" != re.rate )
			{
				setText( "priceinfo", re.rate );
			}
			else
			{
				el( "priceinfo" ).innerHTML = "";
			}
		}

		if( $un != typeof( re.message ) && "" != re.message )
		{
			$msg( re.message, "info", true, null, "infobox" );
			$hide( "infoboxline" );
		}
		else
		{
			setText( "infobox", "" );
		}
	},

 
	// HANDLE RESPONSE
 
 
 	HandleResponse : function( re )
	{
		if( null != re.Id && re.Id > 0 )
		{
			this.CallId = re.Id;
		}

		if( re.CalledAt > 0 )
		{
			this.CalledAt = re.CalledAt;
		}
		
		$show( "callbox" );

		if( "" != re.Ani.Body )
		{
			setText( "callbox", re.Ani.Body );
			$class( "callbox", "minheight2" );
		}

		[ "mainContent", "MyTabContainer", "MyTabContainer1", "directLink" ].each( $hide );
		$show( "spacer2" );
		
		if( "" != re.Box.Help )
		{
			setText( "bottomhelp", re.Box.Help );
		}

		/* $class( boxtopid, re.Head.BorderClass ); */
		setText( "cboxtitle", re.Head.Text );
		$class( "cboxtitle", re.Head.TextClass );

		if( "" != re.Box.MainBody )
		{
			setText( "main", re.Box.MainBody );
			ExecuteAjaxJS( re.Box.MainBody );
		}
		else
		{
			this.setImg( "imgfrom", re.Ani.FromImage );
			this.setImg( "imgconn", re.Ani.ConnectionImage );
			this.setImg( "imgto", re.Ani.ToImage );

			if( "" != re.Ani.From )
			{
				setText( "fromNb", re.Ani.From );
			}
			
			if( "" != re.Ani.To )
			{
				setText( "toNb", re.Ani.To );
			}

			if( "" != re.RateInfo )
			{
				setText( "callpriceinfo", re.RateInfo );
			}
		}
		
		if( null != re.ToolTip && !this.partnerMode)
		{
			( function(){ $TT.Show( "calldidinfo", $TT.Cfg( this.Title, this.Body, 'callani',{ show : true }, { width : 240, left : 95, top : -15 }, true ) ); } ).delay( 600, re.ToolTip );
		}
		
		if( re.ShowAds )
		{
			$s( "callani", "paddingTop", "15px" );
			
			var fr = create("IFRAME");
			
			fr.id = "callcontentiframe";
			fr.src = "/engine/campaign.ashx?id=" + this.CallId;
			fr.width = "416";
			fr.height = "280";
			fr.frameBorder = 0;
			fr.style.display = "block";
			fr.style.margin = "5px auto";
			fr.scrolling = "no";
			
			var efr = el( fr.id );
			if( null != efr )
			{
				efr.parentNode.replaceChild( fr, efr );
			}
			else
			{
				var d = create("DIV");
				d.className = "cboxline";
				el( "callbox" ).insertBefore( d, el( "callbox" ).firstChild );
				el( "callbox" ).insertBefore( fr, el( "callbox" ).firstChild );
			}
		}
		
		setText( "infobox", re.Box.InfoBody );

		if( "" != re.Box.BottomBody )
		{
			$tog( "callbox2", "clear" != re.Box.BottomBody );
			setText( "callboxbottom", re.Box.BottomBody );
		}
		
		//ExecuteAjaxJS( re.Box.AdsBody );
	},


	setImg : function( n, s )
	{
		if( "" == s )
		{
			return;
		}

		var o = document.images[ n ];

		if( null == o || ( null != o.getAttribute( "vsrc" ) && s == o.getAttribute( "vsrc" ) ) )
		{
			return;
		}
		
		o.setAttribute( "vsrc", s );
		o.src = "/images/animations/" + s;
	},


	// AFTER A CALL:


	CallAgain : function()
 	{
 		redirect( "./" );
 	},


 	GoHome : function()
 	{
 		redirect( "./");
 	},


 	SaveNumberCB : function( a, re, ok )
	{
		if( $un != typeof a && null != a )
		{
			$enable( a );
		}
		
		if( !ok || null == re )
		{
			return;
		}
		
		if( re.Error )
		{
			setText( "infobox", re.Box.InfoBody );
		}
		else if( re.ShowEmptyCallForm )
		{
			redirect( "./" + ( this.NoCash ? "?rc=noca" : "" ) );
		}
		else
		{
			this.HandleResponse( re );

			foc( "invitationemail" );
		}
	},


 	UpdateNAA : function()
	{
		$X.Post( $X.Url.Account, "UpdateNeverAskAgain", { never : this.f.neveragain.checked }, this.UpdateNAACB.link( this ) ).Send();
	},

	SkipRetryAfterBusy : function()
	{
		var box = el( "DontAskAgainForRetryAfterBusy" );
		if( null == box || !box.checked )
		{
			redirect( "./" + ( this.NoCash ? "?rc=noca" : "" ) );
		}
		else
		{
			$X.Post( $X.Url.Account, "UpdateAskForRetryAfterBusy", { retry : 0 }, this.UpdateNAACB.link( this ) ).Send();
		}
	},

 	UpdateNAACB : function( re, ok )
 	{
 		redirect( "./" + ( this.NoCash ? "?rc=noca" : "" ) );
	},


 	Finish : function()
 	{
 		$X.Post( $X.Url.Call, "FinishCall",
 		{
 			src : this.SerializeFrom(),
 			dests : this.SerializeToList().join( "," ),
 			/* destTypes : this.SerializeToTypeList(), */
 			campaign: this.WebCampaignId
 		}, this.DoFinishCall.link( this ) ).Send();
	},

	DoFinishCall : function( re, ok )
	{
		if( !ok || null == re )
		{
			return;
		}
		
		this.NoCash = re.NoCash;

		if( re.ShowEmptyCallForm )
		{
			redirect( "./" + ( this.NoCash ? "?rc=noca" : "" ) );
		}
		else
		{
			this.HandleResponse( re );
		}
	},


	SendInvitation : function()
	{
		if( "function" != typeof( SendInvitation ) )
		{
			LoadScript( "/js/invite.js", "js_invite" );
			this.SendInvitation.delay( 300, this );
			return;
		}
		SendInvitation();
	},

	UpdateInvNAA : function()
	{
		$X.Post( $X.Url.Account, "UpdateInvitationNeverAskAgain", { never : el( "inviteneveragain" ).checked }, this.UpdateInvNAACB.link( this ) ).Send();
	},

	UpdateInvNAACB : function( re, ok )
	{
		redirect( "./" + ( this.NoCash ? "?rc=noca" : "" ) );
	},

	WebCampaignAction : function( type, re )
	{
		$X.Post( $X.Url.Call, "WebCampaignAction", { cid : this.CallId, campaign : this.WebCampaignId, "type" : type }, null ).Send( !re );
		if( re )
		{
			redirect("./");
		}
	}
};
/* CALL MANAGER END */


/* SMS MANAGER START */
function SmsManager()
{
	this.m_inputvalue = "";
	this.m_input = null;
	this.m_rate = 0;
	this.m_ratetext = "";
	this.CharsPerSMS = 160;
	this.SmsList = [];
}

SmsManager.prototype =
{
	SmsCount : function()
	{
		return this.SmsList.length > 0 ? this.SmsList.length : 1;
	},

	Input : function()
	{
		if( null == this.m_input )
		{
			this.m_input = el( "SmsMessageBox" );
		}
		return this.m_input;
	},

	Signature : function()
	{
		var from = "";
		var fromtel = CallMgr.GetFrom();
		if( null != fromtel && !fromtel.IsPrivate && !DestMgr.HasPrivate() )
		{
			from = "\n" + fromtel.ToString( true );
		}
		return from + "\nsent via www.jajah.com";
	},

	Update : function( f ) /* forced update */
	{
		if( !f && this.m_inputvalue == this.Input().value )
		{
			return;
		}

		this.Split();
		this.UpdateRate();

		el( "smscounter_chars" ).innerHTML = this.m_inputvalue.length;
		el( "smscounter_sms" ).innerHTML = this.SmsList.length;
	},

	Split : function()
	{
		var r = this.m_inputvalue = this.Input().value,
		indexdigits=1,
		x=0;

		this.SmsList = [];
		while(true)
		{
			x++;
			if( x > 100 )
			{
				break;
			}

			if( r.length <= ( this.CharsPerSMS - this.Signature().length - ( this.SmsList.length == 0 ? 0 : this.CreateIndex( "0", "0" ).length ) ) )
			{
				this.SmsList.push( r + this.Signature() );
				break;
			}

			var pos = r.length <= this.CharsPerSMS - this.CreateIndex( "0", "0" ).length ? this.CharsPerSMS - this.CreateIndex( "0", "0" ).length : r.substr( 0, this.CharsPerSMS - this.CreateIndex( "0", "0" ).length ).lastIndexOf( " " );

			/*
			console.log("----------------------------------");
			console.log(r);
			console.log(r.substr(0,this.CharsPerSMS-this.CreateIndex("0","0").length));
			console.log(pos);
			*/

			if( -1 == pos )
			{
				pos = this.CharsPerSMS - this.CreateIndex( "0", "0" ).length;
			}

			/*
			console.log(pos);
			console.log(r.substr(0,pos).trim());
			*/

			this.SmsList.push( r.substr( 0, pos ).rtrim() );
			r = r.substr( pos ).ltrim();
		}

		this.AppendIndex();
	},

	AppendIndex : function()
	{
		var l = this.SmsList.length;

		if( l < 2 )
		{
			return;
		}

		for( var i=1; i <= l ; i++ )
		{
			this.SmsList[ i - 1 ] += this.CreateIndex( i, l );
		}
	},

	CreateIndex : function( i, t )
	{
		return " (" + i + "/" + t + ")";
	},

	UpdateRate : function( msg )
	{
		if( msg )
		{
			var m = /(\[\[)(.*)(\]\])/i.exec( msg );
			if( null != m )
			{
				this.m_rate = _parseFloat( m[2], $T("nr.group"), $T("nr.decimal") );
				this.m_ratetext = msg.replace( /\[\[.*\]\]/gi, "#rate#" );
			}
		}

		if( this.m_rate > 0 )
		{
			setText( "priceinfo", this.m_ratetext.replace( /#rate#/i, ( this.m_rate * this.SmsCount() ).toFixed( 3 ) ) );
		}
		else
		{
			this.ClearRate();
		}
	},

	ClearRate : function()
	{
		el( "priceinfo" ).innerHTML = "";
	},

	Serialized : function()
	{
		return this.SmsList.join( "\t" );
	}
};
/* SMS MANAGER END */
///<reference path="_intellisense.js" />

function ABManager( name )
{
	this._instance = name;
	
	this.AB = [];
	this._AB = [];
	this.Tabs = [];
	this.ActiveTab = -1;
	this.Loaded = false;
	this.EditMode = false;
	this.DirectMode = false;
	
	this.Id = {
		Form : "ABForm",
		EditForm : "ABEditForm",
		PriceInfo : "priceinfo",
		Tabs : "ABTabContainer",
		AddressTable : "ABContactTable",
		AddressList : "contactslist",
		Loader : "ABLoader",
		FormLoader : "ABEditFormLoader",
		Empty : "ABEmpty",
		AddLink : "ABAddLink",
		DeleteLink : "ABDeleteLink",
		ContactInput : "ABContactName",
		ContactEmail : "ABContactEmail",
		CallBox : "callbox",
		EditBox : "editcontact",
		NewGroupName : "ABGroupName",
		NewGroupContactName : "ABGroupContactName",
		NewGroupContactNumber : "ABGroupContactNumber",
		NewGroupContactNumberType : "newNumberType",
		DirectDesc : "directDesc",
		DirectControl : "directControl"
	};
	
	this.PhoneContainer = {
		LL : "ABLandlineContainer",
		OF : "ABOfficeContainer",
		MO : "ABMobileContainer"
	};
	this.EditTelInput = {
		LL : null,
		OF : null,
		MO : null
	};
	
	this.BlankForm = null;
	
	this.EditName = $T("general.edit");
	this.DeleteName = $T("delete").toLowerCase();
	this.ErrorInAfterCallSave = {
		EmptyName : "Empty Name!",
		EmptyNumber : "Empty Number!"
	};
	
	this.MId = "";
	this.Version = -1;
};

ABManager.prototype =
{
    Load : function( id, v )
    {
        if( !!id )
        {
            this.MId = id;
        }
        if( !!v )
        {
            this.Version = v;
        }
        
        $X.Get( $X.Url.Contacts, "LoadAB", { "id" : this.MId, "v" : this.Version }, this.LoadDone.link( this ), false ).Send();
    },
    
	LoadDone : function( re, ok )
	{
	    if( ok )
	    {
		    this.AB = re.ab;
		    this.InitializePhones();
		    this.Tabs = re.tabs;
		    this.RenderTabs();
		    
		    if( $un != typeof( GroupMgr ) && null != GroupMgr )
		    {
		        GroupMgr.Load( re.groups, re.groupcontacts );
		    }
		    
		    if( $un != typeof( RedialManager ) && null != RedialManager )
		    {
		        RedialManager.render();
		    }

		    if( $un != typeof( CallMgr ) && null != CallMgr )
		    {
		        CallMgr.Changed = true;
		        CallMgr.CalcRate();
		    }
		}
	},
	
	InitializePhones : function()
	{
		this._AB = this.AB.clone();
		for( var i = 0, len = this.AB.length; i < len; i++ )
		{
			var ABi = this.AB[i],
			tel;
			
			for( var j = 2; j < 5; j++ )
			{
				if( null != ABi[j] )
				{
					switch( ABi[8] )
					{
						case 1:
							// is hidden nr
							tel = new TelObj().CreateHidden( ABi[j][0] );
							break;
						case 2:
							// is private
							tel = new TelObj().CreatePrivate( ABi[7], j - 1, ABi[j][0] );
							break;
						default:
							tel = $Tel.FromSerialized( ABi[j][0] );
							break;
					}
					
					if( null != tel )
					{
						ABi[j][0] = tel;
					}
					else
					{
						ABi[j] = null;
					}
				}
			}
		}
	},
	
	RenderTabs : function()
	{
		var cont = el( this.Id.Tabs );
		if( null == cont )
		{
			return;
		}
		
		var html = "";
		
		if( this.IsEmpty() )
		{
			$hide( this.Id.Loader );
			$show( this.Id.Empty );
			return;
		}
		
		for( var i = 0, len = this.Tabs.length; i < len; i++ )
		{
			html += ( '<div class="tab2-l" id="tab{0}x1">&nbsp;</div><div class="tab2" id="tab{0}x2">' +
				'<a href="#" onclick="if($notify){Notify(false)};' + this._instance + '.ShowTab({0});this.blur();return false;">' + this.Tabs[i] + '</a>' +
				'</div><div class="tab2-r" id="tab{0}x3">&nbsp;</div>' ).replace( /\{0\}/g, i );
		}
		
		cont.innerHTML = html;
		this.ShowTab( 0 );
	},
	
	ShowTab : function( i )
	{
		if( i == this.ActiveTab )
		{
			return;
		}
		
		if( this.ActiveTab > -1 )
		{
			if( this.ActiveTab > 0 )
			{
				$class( "tab" + ( this.ActiveTab -1 ) + "x3", "tab2-r" );
			}
			$class( "tab" + this.ActiveTab + "x1", ( 0 == this.ActiveTab ? "tab2-l2" : "tab2-l" ) );
			$class( "tab" + this.ActiveTab + "x2", "tab2" );
			$class( "tab" + this.ActiveTab + "x3", "tab2-r" );
		}
		
		if( i > 0 )
		{
			$class( "tab" + ( i - 1 ) + "x3", "tab2" );
		}
		$class( "tab" + i + "x1", "tab-l" );
		$class( "tab" + i + "x2", "tab" );
		$class( "tab" + i + "x3", "tab-r" );
		
		this.ActiveTab = i;
		this.RenderContacts( i );
	},
	
	RenderContacts : function( nr )
	{
		var row = 0,
		list = el( this.Id.AddressList );
		
		for( var i = list.childNodes.length - 1; i >= 0; i-- )
		{
			list.removeChild( list.childNodes[i] );
		}
		
		for( var i = 0, len = this.AB.length; i < len; i++ )
		{
			var c = this.GetContact( i, nr );
			if( null != c )
			{
				list.appendChild( this.GetRow( c, ++row, i ) );
			}
		}
		
		if( !this.Loaded )
		{
			this.HideLoader( true );
		}
	},
	
	HideLoader : function( b )
	{
		$tog( this.Id.Tabs, b );
		$tog( this.Id.AddressTable, b );
		$tog( this.Id.Loader, !b );
		
		this.Loaded = b;
	},
	
	HideFormLoader : function( b )
	{
		$tog( this.Id.FormLoader, !b );
	},
	
	GetContactNameAndNumberType : function( tel )
	{
		var contact = null,
		name = "",
		contactid = -1,
		type = "",
		typeint = -1,
		types = [
			"land",
			"office",
			"mobile"
		];
		
		if( "string" == typeof( tel ) )
		{
			tel = $Tel.Create( tel );
		}
		
		if( null == tel )
		{
			return null;
		}
		
		if( this.AB.length > 0 || GroupMgr.Contacts.length > 0 )
		{
			for( var i = 0, len = this.AB.length; i < len && null == contact; i++ )
			{
				var ABi = this.AB[i];
				
				for( var j = 0; j < 3; j++ )
				{
					if( null != ABi[j+2] )
					{
						if( tel.IsEqual( ABi[j+2][0] ) )
						{
							contact = ABi;
							name = contact[1];
							type = types[j];
							typeint = j;
							contactid = ABi[0];
							break;
						}
					}
				}
			}
			
			if( null == contact )
			{
				var groupContact = null,
				isGroupContact = false;
				
				for( var i = 0, len = GroupMgr.Contacts.length; i < len; i++ )
				{
					groupContact = GroupMgr.GetContact( i );
					
					if( null != groupContact )
					{
						var gr_tel = $Tel.Create( "+" + groupContact.Number ); // should be rewritten - the ab_list should already provide serialized numbers, not strings
						
						if( tel.IsEqual( gr_tel ) )
						{
							typeint = groupContact.NumberType;
							if( 0 <= typeint && 2 >= typeint )
							{
								name = groupContact.Name;
								type = types[ typeint ];
								contactid = groupContact.ContactId;
								break;
							}
						} 
					}
				}
			}
		}
		
		if( null != contact || isGroupContact )
		{
			return {
				Name		: name,
				Type		: type,
				DialCode	: tel.DialCode,
				Number		: tel.Number,
				Extension	: tel.Extension,
				Telelphone	: tel,
				typeInt		: typeint,
				ContactId	: contactid
			};
		}
		
		return null;
	},
	
	GetNumber : function( cIndex, i, for_render )
	{
		var c = this.AB[cIndex];
		
		if( null != c[i] )
		{
			var tel = c[i][0],
			rl = null;
			
			if( for_render )
			{
				rl = create( "A" );
				rl.href = "#";
				
				if( 1 == c[i][1] )
				{
					rl.className = "forfree";
				}
				
				AttachEvent( rl, "click", function( e ){ if( $notify ){ Notify( false ) }; CallMgr.SelectContact( tel, cIndex ); preventDefaultEvent( e ); return false; } );
				
				rl.innerHTML = tel.Encrypt( true );
			}
			
			return {
				RenderLink : rl, //'<a href="#" ' + ( 1 == c[i][1] ? 'class="forfree" ' : '' ) + 'onclick="CallMgr.SelectContact(\'' + tel.Serialize() + '\',' + cIndex + ');return false;">' + tel.Encrypt( true ) + '</a>',
				Telephone : tel,
				IsFree : ( 1 == c[i][1] )
			};
		}
		return { RenderLink : "&nbsp;" };
	},
	
	GetContact : function( i, for_render_tab )
	{
		if( this.AB.length <= i )
		{
			return null;
		}
		
		if( $un == typeof( for_render_tab ) )
		{
			for_render_tab = "";
		}
		
		var contact = this.AB[i],
		tab = String( contact[5] );
		
		for_render_tab = String( for_render_tab );
		if( "" != for_render_tab && for_render_tab != tab )
		{
			return null;
		}
		
		return {
			Tab : tab,
			Id : contact[0],
			Name : contact[1],
			Email : contact[6],
			LandLine : this.GetNumber( i, 2, for_render_tab == tab ),
			Office : this.GetNumber( i, 3, for_render_tab == tab ),
			Mobile : this.GetNumber( i, 4, for_render_tab == tab ),
			Type : contact[8],
			Hash : contact[7]
		};
	},
	
	LoadForm : function( html )
	{
		this.HideError();
		this.BlankForm = html;
		el( this.Id.EditForm ).innerHTML = html.replace( /\[[^\]]*\]/g, "" );
	},
	
	ShowForm : function( b )
	{
		this.HideError();
		this.HideFormLoader( true );
		
		//***** el( this.Id.AddLink ).style.visibility = b ? "hidden" : "visible";
		
		//Direct page don't have a GroupMgr
		
		if( typeof GroupMgr != "undefined" && el( GroupMgr.Id.AddLink ) != null )
		{
			el(GroupMgr.Id.AddLink).style.visibility=b?"hidden":"visible";
		}
		
		$tog( this.Id.EditForm, b );
		$tog( this.Id.CallBox, !b );
		$tog( this.Id.EditBox, b );
		$tog( this.Id.PriceInfo, !b );
		
		if(this.DirectMode)
		{
			$tog( this.Id.DirectDesc, !b );
			$tog( this.Id.DirectControl, !b );
		}
			
		if( b )
		{
			foc( this.Id.ContactInput );
		}
	},
	
	ToggleCallFormDisplay : function( show )
	{
		$hide( GroupMgr.Id.EditBox );
		$hide( GroupMgr.Id.EditForm );
		$tog( this.Id.CallBox, show );
		$tog( this.Id.EditBox, !show );
	},
	
	RenderNrInputControls : function( l, o, m )
	{
		this.EditTelInput.LL = NrControlMgr.CreateControl( "abedit_ll", "destination", null, l || DestMgr.DefDC, this.PhoneContainer.LL, true, null );
		this.EditTelInput.OF = NrControlMgr.CreateControl( "abedit_of", "destination", null, o || DestMgr.DefDC, this.PhoneContainer.OF, true, null );
		this.EditTelInput.MO = NrControlMgr.CreateControl( "abedit_mo", "destination", null, m || DestMgr.DefDC, this.PhoneContainer.MO, true, null );	
	},
	
	AddContact : function()
	{
		this.HideError();
		//this.ToggleCallFormDisplay( false );
		this.HideFormLoader( false );
		if( null == this.BlankForm )
		{
			$X.Get( $X.Url.Contacts, "RenderAddressBookForm", { l : $T("l") }, this.RenderAddContactForm.link( this ), false ).Send();
		}
		else
		{
			this.RenderAddContactForm.delay( 20, this, null );
		}
		
		if(this.DirectMode)
		{
			$hide("directDesc");
			$hide("directControl");
		}
	},
	
	RenderAddContactForm : function( res, ok )
	{
		if( ok )
		{
			this.LoadForm( res );
		}
		
		el( this.Id.EditForm ).innerHTML = this.BlankForm.replace( /\[name\]/g, "" ).replace( /\[email\]/g, "" ).replace( /\[id\]/g, "-1" );
		$hide( this.Id.DeleteLink );
		
		this.RenderNrInputControls();
		
		this.ShowForm( true );
	},
	
	EditContact : function( i )
	{
		this.HideError();
		this.ToggleCallFormDisplay( false );
		this.HideFormLoader( false );
		
		if( null == this.BlankForm )
		{
			$X.Get( $X.Url.Contacts, "RenderAddressBookForm", { l : $T("l") }, this.RenderEditContactForm.link( this, i ), false ).Send();
		}
		else
		{
			this.RenderEditContactForm.delay( 20, this, i, null, true );
		}
	},
	
	RenderEditContactForm : function( id, res, ok )
	{
		if( null != res && ok )
		{
			this.LoadForm( res );
		}
		
		var c = this.GetContact( id );
		
		el( this.Id.EditForm).innerHTML = this.BlankForm.replace( /\[name\]/g, encode( c.Name ) ).replace( /\[email\]/g, encode( c.Email ) ).replace( /\[id\]/g, id );
		
		this.RenderNrInputControls( c.LandLine.Telephone, c.Office.Telephone, c.Mobile.Telephone );
		
		this.ShowForm( true );
	},
	
	DeleteContact : function( i )
	{
		this.HideError();
		var c = this.GetContact( i );
		if( null != c )
		{
			var id = c.Id,
			func = "DeleteContact";
			
			if( -1 == c.Id )
			{
				id = c.Hash;
				func = "RemovePublicUserFromAddressbook";
			}
			
			$X.Post( $X.Url.Contacts, func, { "id" : id }, this.ContactDeleted.link( this ) ).Send();
		}
	},
	
	ContactDeleted : function( res, ok)
	{
		$enable( "_ABdelbtn" );
		if( "ok" != res )
		{
			this.HandleResponse( res, ok );
			this.ShowForm( false );
		}
		
		this.Reload();
		
		var g = null,
		gIds = [];
		
		for( var i = 0, len = GroupMgr.Groups.length; i < len; i++ )
		{
			g = GroupMgr.GetGroup(i);
			if( null != g )
			{
				if( !GroupMgr.HasContactsInGroup( g.Id ) )
				{
					gIds.push( g.Id );
				}
			}
		}
		
		if( gIds.length > 0 )
		{
			$X.Post( $X.Url.Contacts, "DeleteGroups", { "groups" : gIds }, GroupMgr.UpdateComplete.link( this ) ).Send();
		}
	},
	
	SaveContact : function( i )
	{
		this.HideError();
		
		var n = el( this.Id.ContactInput ).value,
		eml = el( this.Id.ContactEmail ).value,
		ll = NrControlMgr.GetTel( null, this.EditTelInput.LL ),
		of = NrControlMgr.GetTel( null, this.EditTelInput.OF ),
		mo = NrControlMgr.GetTel( null, this.EditTelInput.MO ),
		data = { "name" : n, "email" : eml, "ll" : formatPhone( ll ), "of" : formatPhone( of ), "mo" : formatPhone( mo ) };
		
		if( -1 == i )
		{
			$X.Post( $X.Url.Contacts, "AddContact", data, this.CompleteSave.link( this ) ).Send();
		}
		else
		{
			data.id = this.GetContact( i ).Id;
			
			$X.Post( $X.Url.Contacts, "UpdateContact", data, this.CompleteSave.link( this ) ).Send();
		}
		
		function formatPhone( tel )
		{
			return null != tel ? tel.ToString() : "";
		}
	},
	
	CompleteSave : function( res, ok )
	{
		$enable( "_ABsavebtn" );
		if( !this.HandleResponse( res, ok ) )
		{
			return;
		}
		this.ShowForm( false );
		
		if( this.DirectMode )
		{
			location.reload( true );
		}
		else
		{
			this.Reload();
		}
	},
	
	GetRow : function( c, r, i )
	{
		var tr = create( "TR" );
		
		if( 0 == r % 2 )
		{
			tr.className = "alternate";
		}
		
		tr.appendChild( this.GetCell( "<div>" + c.Name + "</div>", "abname" ) );
		tr.appendChild( this.GetCell( c.LandLine.RenderLink ) );
		tr.appendChild( this.GetCell( c.Office.RenderLink ) );
		tr.appendChild( this.GetCell( c.Mobile.RenderLink ) );
		tr.appendChild( this.GetCell( 0 == c.Type ? '<a href="#" onclick="if($notify){Notify(false)};' + this._instance + '.EditContact(' + i + ');return false;" class="editlink">' + this.EditName + '</a>' : '<a href="#" onclick="' + this._instance + '.DeleteContact(' + i + ');return false;" class="editlink">' + this.DeleteName + '</a>' ) );
		
		return tr;
	},
	
	GetCell : function( html, css )
	{
		var td = create( "TD" );
		if( $un != typeof( css ) )
		{
			td.className = css;
		}
		if( null != html && $un != typeof( html.tagName ) )
		{
			td.appendChild( html );
		}
		else
		{
			td.innerHTML = html;
		}
		return td;
	},
	
	Reload : function()
	{
		$hide( this.Id.Empty );
		
		this.HideError();
		this.ActiveTab = -1;
		this.HideLoader( false );
		
		this.Load();
	},
	
	HideError : function()
	{
		$hide( "infoboxline2" );
		$hide( "infobox" );
		el( "infobox" ).innerHTML = "";
	},
	
	IsEmpty : function()
	{
		return 0 == this.Tabs.length;
	},
	
	HandleResponse : function( res, ok )
	{
		if( ok && null != res )
		{
			if( "ok" == res.status )
			{
				this.Version = res.ABId;
				return true;
			}
			else
			{
				$msg( res.message.text, res.message.type, true, null, "infobox" );
				if( this.DirectMode )
				{
					$show("infoboxline2");
				}
			}
		}
		return false;
	}
};

///<reference path="_intellisense.js" />

function GroupManager( name )
{
	this._instance = name;
	
	/*object arrays*/
	this.Groups = [];
	this.Contacts = [];
	this.AfterCallNumberCache = null;
	
	/*constants*/
	this.MAX_MEMBERS = 10;
	
	/*init check*/
	this.Loaded = false;
	
	/*dhtml ids*/
	this.Id = {
		AddressTable : "ABGroupsTable",
		AddressList : "groupslist",
		Loader : "ABGroupLoader",
		Empty : "ABGroupEmpty",
		AddLink : "ABGroupAddLink",
		CallBox : "callbox",
		EditBox : "editcontact",
		EditForm : "ABEditForm",
		DeleteButton : "ABGroupDeleteLink",
		AddLink : "ABGroupAddLink",
		TemplateHtmlId : "ABGroupEditContactsContainer",
		GroupName : "ABGroupName",
		FormLoader : "ABEditFormLoader"
	};
	
	this.EditTelInput = []; // array of nr-input controls
	
	/*form html*/
	this.BlankForm = null;
	this.BlankNumberTemplate = [];
	
	/*parameter*/
	this.IndexEnum = 0;
	this.ParticipantCount = 0;
	this.EditMode = false;
	
	/*text strings*/
	this.EditName = $T( "general.edit" ).toLowerCase();
	
	this.Load = function( groups, contacts )
	{
		this.Groups = groups;
		this.Contacts = contacts;
		this.InitializePhones();
		this.RenderList();
	};
	
	this.InitializePhones = function()
	{
		for( var i = 0, len = this.Contacts.length; i < len; i++ )
		{
			this.Contacts[i][2] = $Tel.FromSerialized( this.Contacts[i][2] );;
		}
	};
	
	this.RenderList = function()
	{
		var row=0,
		list = el( this.Id.AddressList );
		
		if( null == list )
		{
			return;
		}
		
		if( this.HasGroup() )
		{
			$hide( this.Id.Empty );
			$show( this.Id.AddressTable );
		}
		else
		{
			$hide( this.Id.Loader );
			$hide( this.Id.AddressTable );
			$show( this.Id.Empty );
			return;
		}
		
		for( var i = list.childNodes.length - 1; i >= 0; i-- )
		{
			list.removeChild( list.childNodes[i] );
		}
		
		for( var i = 0, len = this.Groups.length; i < len; i++ )
		{
			list.appendChild( this.CreateRow( this.GetGroup(i), ++row, i ) );
		}
		
		if( !this.Loaded )
		{
			this.ShowHideListLoader( false );
		}
	};
	
	this.HasGroup = function()
	{
		return this.Groups.length > 0;
	};
	
	this.GetGroup = function( i )
	{
		return this.Groups.length > i ? { Name : this.Groups[i][1], Id : this.Groups[i][0] } : null;
	};
	
	this.GetContact = function( i )
	{
		if( this.Contacts.length < i )
		{
			return null;
		}
		
		var c = this.Contacts[i];
		return { 
			GroupID : c[0],
			Name : c[1],
			Number : c[2],
			NumberType : c[3],
			DialCode : c[5],
			ContactId : c[6]
		};
	};
	
	this.HasContactsInGroup = function( id )
	{
		for( var i = 0, len = this.Contacts.length; i < len; i++ )
		{
			if( this.Contacts[i][0] == id )
			{
				return true;
			}
		}
		return false;
	};
	
	this.GetParticipantInputFields = function( i )
	{
		var ids = [ "ABGroupContactName_0_", "ABGroupNumberContainer_0_", "ABGroupContactHome_0_", "ABGroupContactOffice_0_", "ABGroupContactMobile_0_" ];
		var inputs = {
			name : el( this.ReplaceEnum( ids[0], i ) ),
			nr : el( this.ReplaceEnum( ids[1], i ) ),
			types : {
				home : el( this.ReplaceEnum( ids[2], i ) ),
				office : el( this.ReplaceEnum( ids[3], i ) ),
				mobile : el( this.ReplaceEnum( ids[4], i ) )
			}
		};
		
		if( null == inputs.name || null == inputs.nr )
		{
			return null;
		}
		
		return inputs;
	};
	
	this.GetParticipantInput = function( i )
	{
		var inputs = this.GetParticipantInputFields( i );
		if( null == inputs )
		{
			return null;
		}
		
		var nrcontrol = this.GetControlForContainer( inputs.nr ),
		nrvalue = "";
		
		if( null != nrcontrol )
		{
			nrvalue = NrControlMgr.GetTel( "", nrcontrol );
		}
		
		return {
			name : inputs.name.value.trim(),
			type : ( inputs.types.home.checked ? 0 : ( inputs.types.office.checked ? 1 : 2 ) ),
			tel : nrvalue,
			control : nrcontrol
		};
	};
	
	this.SetSlotValues = function( i, p, ctrl )
	{
		var inputs = this.GetParticipantInputFields( i );
		
		if( $un == typeof( ctrl ) || null == ctrl )
		{
			ctrl = this.GetControlForContainer( inputs.nr );
		}
		
		if( null == inputs || null == ctrl )
		{
			return false;
		}
		
		inputs.name.value = p.name;
		
		ctrl.Number.value = p.number.ToString( true );
		splitNumber( ctrl );
		foc( ctrl.Number );
		
		return true;
	};
	
	this.GetParticipantValueObject = function( n, t, nr, i )
	{
		return {
			name : n,
			type : t,
			number : ( null == nr || $Tel.IsTelObj( nr ) ? nr : $Tel.Create( nr ) ),
			id : i
		};
	};
	
	this.ReplaceEnum = function( txt, i )
	{
		return txt.replace( /_0_/g, i );
	};
	
	this.GetABEntry = function( tel, start )
	{
		if( "string" == typeof( tel ) )
		{
			tel = $Tel.Create( tel );
		}
		
		var end = ABMgr.AB.length;
		if( $un == typeof( start ) )
		{
			start = 0;
		}
		else
		{
			end = start++;
		}
		
		var types = [ "land", "office", "mobile" ];
		
		for( var i = start; i < end; i++ )
		{
			for( var j = 0; j < types.length; j++ )
			{
				if( null != ABMgr.AB[i][j+2] )
				{
					if( tel.IsEqual( ABMgr.AB[i][j+2][0] ) )
					{
						return this.GetParticipantValueObject( ABMgr.AB[i][1], j, ABMgr.AB[i][j+2][0], ABMgr.AB[i][0] );
					}
				}
			}
		}
	};
	
	this.NumbersExistInAB = function( tels )
	{
		for( var i = 0, len = tels.length; i < len; i++ )
		{
			if( null == this.GetABEntry( tels[i] ) )
			{
				return false;
			}
		}
		return true;
	};
	
	this.CreateCell = function( html, css )
	{
		var td = create("TD");
		if( $un != typeof( css ) )
		{
			td.className = css;
		}
		td.innerHTML = html;
		return td;
	};
	
	this.CreateRow = function( g, r, i )
	{
		var tr = create("TR");
		if( r % 2 == 0 )
		{
			tr.className = "alternate";
		}
		tr.appendChild( this.CreateCell( "<div>" + g.Name + "</div>", "abname" ) );
		
		var members = [];
		
		if( this.HasContactsInGroup( g.Id ) )
		{
			for( var j = 0, len = this.Contacts.length; j < len; j++ )
			{
				var contact = this.GetContact( j );
				if( null != contact && g.Id == contact.GroupID )
				{
					members.push( "" != contact.Name ? contact.Name : contact.Number.ToString( true ) );
				}
			}
		}
		
		if( 0 == members.length )
		{
			members.push( "none" );
		}
		
		tr.appendChild( this.CreateCell( '<a href="#" onclick="if(!$notify){' + this._instance + '.Select(' + g.Id + ');}return false;" >' + members.join(", ") + ' ...</a>' ) );
		tr.appendChild( this.CreateCell( '<a href="#" onclick="if(!$notify){' + this._instance + '.Edit(' + i + ');}return false;" class="editlink">' + this.EditName + '</a>' ) );
		
		return tr;
	};

	this.SerializeList = function( list, forcompare )
	{
		if( $un == typeof( forcompare ) )
		{
			forcompare = false;
		}
		
		var tmp = [];
		for( var i = 0, len = list.length; i < len; i++ )
		{
			tmp.push( list[i].Serialize( forcompare ) );
		}
		return tmp.join( "," );
	};

	/* CRUD-methods */
	
	this.Select = function( id )
	{
		if( this.HasContactsInGroup( id ) )
		{
			var phones = [];
			for( var i = 0, len = this.Contacts.length; i < len; i++ )
			{
				var contact = this.GetContact( i );
				if( contact.GroupID == id )
				{
					phones.push( contact.Number );
				}
			}
			DestMgr.SetGroup( phones );
			CallMgr.CalcRate();
		}
	};
	
	this.Delete = function( id )
	{
		this.HideError();
		$X.Post( $X.Url.Contacts, "DeleteGroup", { "id" : id }, this.UpdateComplete.link( this ) ).Send();
	};
	
	this.Save = function( id )
	{
	    $enable("saveButtonInAB");
		var container = el( this.Id.TemplateHtmlId );
		if( null == container )
		{
			return null;
		}
		
		this.HideError();
		
		var groupname = el( this.Id.GroupName ).value.trim();
		
		if( "" == groupname )
		{
			$enable( "_GRPsavebtn" );
			return $msg( $T( "save.error.name.empty" ), "error", true, null, "infobox" );
		}
		
		var numbers = [],
		types = [ 
			"land",
			"office",
			"mobile"
		];
		
		var index = -1;
		for( var i = 0, len = container.childNodes.length; i < len; i++ )
		{
			if( ( container.childNodes[i].indexEnum || -1 ) == index )
			{
				continue;
			}
			
			index = ( container.childNodes[i].indexEnum || -1 );
			
			var values = this.GetParticipantInput( index );
			
			if( null == values )
			{
				continue;
			}
			
			if( "" == values.name )
			{
				$enable( "_GRPsavebtn" );
				return $msg( $T( "save.error.name.empty" ), "error", true, null, "infobox" );
			}
			
			if( null == values.tel )
			{
				$enable( "_GRPsavebtn" );
				return $msg( $T( "save.error.number.empty"), "error", true, null, "infobox" );
			}
			
			var p = this.GetABEntry( values.tel );
			if( null != p )
			{
				numbers.push( [ values.tel.Serialize(), p.type, p.name, p.id ].join( "@;;@" ) );
			}
			else
			{
				numbers.push( [ values.tel.Serialize(), values.type, values.name, "-1" ].join( "@;;@" ) );
			}
		}
		
		var data = { name : groupname, nr : numbers };
		
		if( -1 == id )
		{
			$X.Post( $X.Url.Contacts, "AddGroup", data, CallMgr.SaveNumberCB.link( CallMgr, "_GRPsavebtn" ) ).Send();
		}
		else
		{
			data.id = id;
			$X.Post( $X.Url.Contacts, "UpdateGroup", data, CallMgr.SaveNumberCB.link( CallMgr, "_GRPsavebtn" ) ).Send();
		}
	};
	
	this.UpdateComplete = function( res, ok )
	{
		$enable( "_GRPdelbtn" );
		if( !ABMgr.HandleResponse( res, ok ) )
		{
			return;
		}
		this.ShowHideForm( false );
		ABMgr.Reload();
	};
	
	this.Add = function()
	{
		this.Edit( null );
	};
	
	this.Edit = function( id )
	{
		this.HideError();
		this.ToggleCallFormDisplay( false );
		this.ShowHideFormLoader( true );
		
		$hide( this.Id.EditForm );
		
		if( null == this.BlankForm )
		{
			$X.Get( $X.Url.Contacts, "RenderAddressBookGroupForm", { l : $T("l") }, this.RenderForm.link( this, id ), false ).Send();
		}
		else
		{
			this.RenderForm.delay( 20, this, id, null, ok );
		}
	};
	
	this.AfterGroupCall = function( tels )
	{
		this.AfterCallNumberCache = [];
		var detail = null;
		
		if( this.NumbersExistInAB( tels ) )
		{
			return;
		}
		
		for( var i = 0, len = tels.length; i < len; i++ )
		{
			this.AfterCallNumberCache.push( tels[i] );
			
			detail = this.GetABEntry( tels[i] );
			
			if( null != detail )
			{
				switch( detail.type )
				{
					case "mobile":
						$html( "ExistentType" + i, el( "holdTypeMobile" ).value );
						break;
					case "office":
						$html( "ExistentType" + i, el( "holdTypeOffice" ).value );
						break;
					case "land":
						$html( "ExistentType" + i, el( "holdTypeHome" ).value );
						break;
					default:
						break;
				}
				
				$html( "ExistentName" + i, detail.name );
			}
		}
	};
	
	this.DontSave = function( a )
	{
		CallMgr.UpdateNAA();
		$X.Post( $X.Url.Contacts, "JustInviteScreen", { nr : this.SerializeList( this.AfterCallNumberCache ), campaign : CallMgr.WebCampaignId }, CallMgr.SaveNumberCB.link( CallMgr, a ) ).Send();
	};
	
	this.SaveNewGroup = function( a )
	{
		var type = -1,
		oldcontactdetail = null,
		numbers = this.AfterCallNumberCache,
		sendNumbers = [];
		
		for( var i = 0, len = this.AfterCallNumberCache.length; i < len; i++ )
		{
			oldcontactdetail = this.GetABEntry( this.AfterCallNumberCache[i] );
			
			if( null == oldcontactdetail )
			{
				var fields = document.getElementsByName( "newNumberType" + i );
				
				if( fields[0].checked )
				{
					type = 0;
				}
				else if( fields[1].checked )
				{
					type = 1;
				}
				else if( fields[2].checked )
				{
					type = 2;
				}
				
				if( !el( "GroupNameCheckBox" ).checked )
				{
					if( "" == el( "newNumberName" + i ).value.trim() )
					{
						$msg( $T( "save.error.name.empty" ), "error", true, null, "infobox" );
						$enable( a );
						return;
					}
				}
				
				sendNumbers.push(this.AfterCallNumberCache[i].Serialize() + '@;;@' + type + '@;;@' + el('newNumberName'+i).value.trim() + '@;;@-1');
			}
			else
			{
				sendNumbers.push(this.AfterCallNumberCache[i].Serialize() + '@;;@' + oldcontactdetail.type + '@;;@' + oldcontactdetail.name + '@;;@' + oldcontactdetail.id);
			}
		}
		
		var data =
		{
			"new"	 : false,
			nr		 : sendNumbers,
			never	 : el( "neveragain" ).checked,
			campaign : CallMgr.WebCampaignId
		};
		
		if( el( "GroupNameCheckBox" ).checked )
		{
			data["new"] = true;
			data.name = el( "newGroupName" ).value;
		}
		
		$X.Post( $X.Url.Contacts, "SaveNumberGroup", data, CallMgr.SaveNumberCB.link( CallMgr, a ) ).Send();
	};
	
	/* form rendering */
	
	this.RenderForm = function( id, res, ok )
	{
		if( null != res )
		{
			var arr = res.split( "<!--delimiter-->" );
			
			this.BlankForm = arr[0];
			
			for( var i = 1, len = arr.length; i < len; i++ )
			{
				this.BlankNumberTemplate.push( arr[i] );
			}
		}
		
		var g = null;
		
		if( null != id )
		{
			g = this.GetGroup( id );
		}
		
		el( this.Id.EditForm ).innerHTML = this.BlankForm.replace( /\[id\]/gi, null == g ? -1 : g.Id );
		
		this.ClearParticipants();
		
		if( null == g )
		{
			//add group
			this.AppendParticipant( null );
			$hide( this.Id.DeleteButton );
		}
		else
		{
			//edit group
			el( this.Id.GroupName ).value = g.Name;
			for( var i = 0, len = this.Contacts.length; i < len; i++ )
			{
				if( this.Contacts[i][0] == g.Id )
				{
					this.AppendParticipant( this.GetParticipantValueObject( this.Contacts[i][1], this.Contacts[i][3], this.Contacts[i][2], this.Contacts[i][6] ), true );
				}
			}
		}
		
		this.UpdateDeleteLinks();
		this.ShowHideForm( true );
	};
	
	this.GetAllNumberControls = function()
	{
		var container = el( this.Id.TemplateHtmlId ),
		result = [];
		
		if( null != container )
		{
			var ctrls = container.getElementsByTagName( "SELECT" );
			
			for( var i = 0, len = ctrls.length; i < len; i++ )
			{
				result.push( ctrls[i]["_Controls"] );
			}
		}
		return result;
	};
	
	this.UpdateDeleteLinks = function()
	{
		var ctrls = this.GetAllNumberControls();
		
		for( var i = 0, len = ctrls.length; i < len; i++ )
		{
			ctrls[i].Delete.style.display = this.ParticipantCount > 1 ? "" : "none";
		}
	};
	
	this.ClearParticipants = function()
	{
		var container = el( this.Id.TemplateHtmlId );
		if( null == container )
		{
			return;
		}
		
		for( var i = container.childNodes.length - 1; i >= 0; i-- )
		{
			container.removeChild( container.childNodes[i] );
		}
		this.ParticipantCount = 0;
		this.IndexEnum = 0;
	};
	
	this.AppendParticipant = function( p, nolimit )
	{
		if( $un == typeof( nolimit ) )
		{
			nolimit = false;
		}
		
		if( this.ParticipantCount >= 10 && !nolimit )
		{
			return;
		}
		
		var container = el( this.Id.TemplateHtmlId );
		if( null == container )
		{
			return;
		}
		
		this.ParticipantCount++;
		this.IndexEnum++;
		
		if( null == p )
		{
			p = this.GetParticipantValueObject( "", 0, null, -1 );
		}
		
		for( var i = 0, len = this.BlankNumberTemplate.length; i < len; i++ )
		{
			var html = this.ReplaceEnum( this.RenderTypeChecked( this.BlankNumberTemplate[i], p.type ), this.IndexEnum ),
			tr = create("TR"),
			td = create("TD");
			
			td.innerHTML = html;
			tr.appendChild( td );
			tr.indexEnum = this.IndexEnum;
			container.appendChild( tr );
		}
		
		var nrcont = el( this.ReplaceEnum( "ABGroupNumberContainer_0_", this.IndexEnum ) );
		
		var _this = this,
		ix = this.IndexEnum;
		var ctrl = NrControlMgr.CreateControl( "groupnr" + this.IndexEnum, "destination", null, DestMgr.DefDC, nrcont, true, { deleteclick : function(){ _this.DeleteParticipant( ix ); } } );
		
		if( null == ctrl )
		{
			return;
		}
		
		if( p.id > 0 )
		{
			this.SetSlotValues( this.IndexEnum, p, ctrl );
		}
		
		foc( ctrl.Number );
		$tog( "AddParticipantLink2", this.ParticipantCount < 10 );
		this.UpdateDeleteLinks();
	};
	
	this.DeleteParticipant = function( ix )
	{
		var container = el( this.Id.TemplateHtmlId );
		
		if( null == container )
		{
			return;
		}
		
		for( var i = container.childNodes.length - 1; i >= 0; i-- )
		{
			if( container.childNodes[i].indexEnum == ix )
			{
				container.removeChild( container.childNodes[i] );
			}
		}
		
		this.ParticipantCount--;
		
		$tog( "AddParticipantLink2", this.ParticipantCount < 10 );
		this.UpdateDeleteLinks();
	};
	
	this.RenderTypeChecked = function( html, selected )
	{
		var types = [ 
			/{checkedHome}/,
			/{checkedOffice}/,
			/{checkedMobile}/
		];
		
		for( var i = 0; i < 3; i++ )
		{
			html = html.replace( types[i], i == selected ? 'checked="checked"' : '' );
		}
		return html;
	};
	
	this.AppendABEntry = function( tel, ix )
	{
		if( !this.EditMode || ( ABMgr.AB.length - 1 ) < ix )
		{
			return false;
		}
		
		if( tel.IsPrivate )
		{
			return true;
		}
		
		var ctrls = this.GetAllNumberControls();
		
		for( var i = 0, len = ctrls.length; i < len; i++ )
		{
			var t = NrControlMgr.GetTel( "", ctrls[i] );
			if( null != t && t.IsEqual( tel ) )
			{
				return true;
			}
		}
		
		var p = this.GetABEntry( tel );
		if( null != p )
		{
			var freeslot = this.GetFreeSlot();
			if( freeslot > -1 )
			{
				this.SetSlotValues( freeslot, p );
			}
			else
			{
				this.AppendParticipant( p );
			}
		}
		
		return true;
	};
	
	this.GetFreeSlot = function()
	{
		var container = el( this.Id.TemplateHtmlId );
		
		if( null == container )
		{
			return null;
		}
		
		var ix = -1;
		for( var i = 0, len = container.childNodes.length; i < len; i++ )
		{
			if( ( container.childNodes[i].indexEnum || -1 ) == ix )
			{
				continue;
			}
			
			ix = ( container.childNodes[i].indexEnum || -1 );
			if( this.IsEmptySlot( ix ) )
			{
				return ix;
			}
		}
		return -1;
	};
	
	this.IsEmptySlot = function( ix )
	{
		var values = this.GetParticipantInput( ix );
		if( null == values )
		{
			return false;
		}
		return "" == values.name && "" == values.control.Number.value.trim();
	};
	
	this.GetControlForContainer = function( c )
	{
		var f = c.getElementsByTagName( "INPUT" );
		if( f.length > 0 )
		{
			return f[0]["_Controls"];
		}
		return null;
	};
	
	/* show/hide elements */
	
	this.HideError = function()
	{
		$hide( "infoboxline" );
		$hide( "infobox" );
		el( "infobox" ).innerHTML = "";
	};
	this.ToggleCallFormDisplay = function( visible )
	{
		$hide( ABMgr.Id.EditBox );
		$tog( this.Id.CallBox, visible );
		$tog( this.Id.EditBox, !visible );
	};
	
	this.ShowHideListLoader = function( b )
	{
		$tog( this.Id.AddressTable, !b );
		$tog( this.Id.Loader, b );
		this.Loaded=!b;
	};
	
	this.ShowHideFormLoader = function( visible )
	{
		$tog( this.Id.FormLoader, visible );
	};
	
	this.ShowHideForm = function( b )
	{
		this.EditMode = b;
		this.HideError();
		this.ShowHideFormLoader( false );
		
		el( ABMgr.Id.AddLink ).style.visibility = b ? "hidden" : "visible";
		el( this.Id.AddLink ).style.visibility = b ? "hidden" : "visible";
		$tog( this.Id.EditForm, b );
		
		this.ToggleCallFormDisplay( !b );
		
		if(b)
		{
			foc( this.Id.GroupName );
		}
	};
	
	this.ShowHideGroupNameRow = function( b )
	{
		$tog( "groupNameTR", b );
	};
}
///<reference path="_intellisense.js" />


function RedialMgr( name, renderer )
{
	this._instance = name;
	this.cookieName = "";
	this.cookiePath = "/members/";
	this.htmlContainerId = "";
	this.recentCallsList = null;
	this.maxRecentCallsNumber = 10;
	this.renderer = renderer || null;
	
	this.monthsNames = [
		"Jan",
		"Feb",
		"Mar",
		"Apr",
		"May",
		"Jun",
		"Jul",
		"Aug",
		"Sep",
		"Oct",
		"Nov",
		"Dec"
	];
	
    this.init = function( cookieName, htmlContainerId, maxRecentCallsNumber, cookiePath )
    {
		this.cookieName = cookieName;
		if( cookiePath )
		{
			this.cookiePath = cookiePath;
		}

		this.htmlContainerId = htmlContainerId;
		this.maxRecentCallsNumber = maxRecentCallsNumber;

		var recentCallsJson = this.readRecentCallsCookie();
		
		if( null != recentCallsJson )
		{
			var recentCallsObj = Eval( recentCallsJson );
			if( null != recentCallsObj )
			{
				this.recentCallsList = recentCallsObj.rc;
			}
		}
	};
	
	this.render = function()
	{
		if( null != this.recentCallsList )
		{
			this.renderer.renderRecentCallList( this.recentCallsList, this.htmlContainerId );
		}
		else
		{
			el( this.htmlContainerId ).innerHTML = $T( "recent.empty" );
		}
	};
	
	this.readRecentCallsCookie = function()
	{
		var nameEQ = this.cookieName + "=",
		ca = $d.cookie.split( ";" );
		
		for( var i = 0, len = ca.length; i < len; i++ )
		{
			var c = ca[i].ltrim();
            if( 0 == c.indexOf( nameEQ ) )
            {
				return unescape( c.substr( nameEQ.length ) );
			}
		}
		return null;
	};
	
	this.saveNewCall = function( cmgr )
	{
		if( 1 == cmgr.To.length )
		{
			if( null != cmgr.To[0] && !cmgr.To[0].IsPrivate )
			{
				var tel = cmgr.To[ 0 ].ToString( false );
				var index = this.findNumberIndex( tel );
				if( -1 != index )
				{
					this.recentCallsList.splice( index, 1 );
				}
				
				this.recentCallsList.splice( 0, 0, this.createRecentCall( tel ) );
				
				if( this.recentCallsList.length >= this.maxRecentCallsNumber )
				{
					this.recentCallsList.splice( this.maxRecentCallsNumber, 1 );
				}
				$d.cookie = this.cookieName + "=" + urlEncode( this.stringifyRecentCalls() ) + "; path=" + this.cookiePath;
				this.render();
			}
		}
		else if( 0 == cmgr.To.length )
		{
			this.fillLastDialedCall( cmgr );
			return false;
		}
		
		return true;
	};
	
	this.fillLastDialedCall = function( cmgr )
	{
		if( cmgr.To.length <= 1 && this.recentCallsList.length > 0 )
		{
			if( "" == DestMgr.GetControl( 0 ).Number.value.trim() )
			{
				cmgr.SelectContact( "+" + this.recentCallsList[0].n );
				showMyTab(3);
			}
		}
	};
	
	this.stringifyRecentCalls = function()
	{
		var result = '{"rc":[';
		
		for( var i = 0, len = this.recentCallsList.length; i < len; ++i )
		{
			result += '{"n":"' + this.recentCallsList[i].n + '","ct":"' + this.recentCallsList[i].ct + '"}';
			if( i < len - 1 )
			{
				result += ',';
			}
		}
		result += ']}';
		return result;
	};
	
	this.createRecentCall = function( tel )
	{
		var date = new Date();
		var formattedDate = this.monthsNames[ date.getMonth() ] + " " + this.leadingZero( date.getDate() ) + ", " + 
			date.getFullYear() + " " + date.getHours() + ":" + this.leadingZero( date.getMinutes() );
		return Eval( "{'n':'" + tel + "', 'ct':'" + formattedDate + "'}" );
	};
	
	this.leadingZero = function( nr )
	{
		if( nr < 10 )
		{
			nr = "0" + nr;
		}
		return nr;
	};
	
	this.findNumberIndex = function( tel )
	{
		for( var i = 0, len = this.recentCallsList.length; i < len; ++i )
		{
			if( this.recentCallsList[i].n == tel )
			{
				return i;
			}
		}
		return -1;
	};
	
	this.saveRecentCallNumber = function( number )
	{
		$X.Post( $X.Url.Contacts, "SaveRecentCallNumber", { nr : number }, this.recentCallNumberSaveFormLoaded.link( this, number ) ).Send();
	};
	
    this.recentCallNumberSaveFormLoaded = function( nr, res, ok )
    {
		var tel = $Tel.Create( nr );
		
		el( "callbox" ).innerHTML = res.Ani.Body;
		GroupMgr.AfterGroupCall( [ tel ] );
	};
}

function RecentCallsRendererMgr()
{
	this.renderRecentCallList = function( recentCallsList, containingDivId )
	{
		var tableHtml;
		
		if( 0 < recentCallsList.length )
		{
			var contact,
			alternating;
			
            tableHtml = '<br /><table id="recentCallsTable" class="contacts" width="100%" cellspacing="1" cellpadding="0" align="center">' +
						'<colgroup><col width="25%" /><col width="29%" /><col width="40%" /><col width="6%" /></colgroup>' +
						'<tr><th></th><th>' + $T( "recent.number" ) + '</th><th>' + $T( "recent.calltime" ) + '</th><th> </th></tr>' +
						'<tbody id="recentCallsTableBody">';
			
			for( var i = 0, len = recentCallsList.length; i < len; ++i )
			{
			    contact = ABMgr.GetContactNameAndNumberType( recentCallsList[i].n );
				
				alternating = ( 0 == i % 2 );
				tableHtml += this.rowFormat( contact, recentCallsList[i].n, recentCallsList[i].ct, alternating );
			}
			
			tableHtml += "</tbody></table>";
		}
		else
		{
			tableHtml = '<div style="margin-top:13px;" class="emptytab">' + $T( "recent.empty" ) + '</div>';
		}
		
		el( containingDivId ).innerHTML = tableHtml;
	};
	
	this.renderRowNoContact = function( number, callTime, alternating )
	{
		return this.rowFormat( "+" + number, number, callTime, true, alternating );
	};
	
	this.renderRowWithContact = function( contactName, number, callTime, alternating )
	{
		var numberDisplay = "<span dir='ltr'><b>" + contactName + "</b></span> (+" + number + ")";
		return RecentCallsRenderer.rowFormat( numberDisplay, number, callTime, false, alternating );
	};
	
	this.rowFormat = function( contact, number, callTime, alternating )
	{
		var saveHtml = "",
		contactName = "";
		
		if( null == contact )
		{
			saveHtml = '<a class="editlink" href="#" onclick="RedialManager.saveRecentCallNumber(\'' + number + '\');return false;">' + $T( "recent.savelink" ) + "</a>";
		}
		else
		{
			contactName = contact.Name;
		}
		
		return '<tr' + ( alternating ? ' class="alternate"' : '' ) + '><td class="abname"><div>' + contactName + '</div></td><td><a onclick="CallMgr.SelectContact(\'+' + number + '\');return false;" href="#">+' + CryptNumber( number ) + '</a></td><td>' + callTime + '</td><td>' + saveHtml + '</td></tr>\n';
	};
}
///<reference path="_intellisense.js" />

function isParentVisible( id )
{
	var currNode = el( id );
	
	if( null == currNode )
	{
		return false;
	}
	
	while( currNode != $d )
	{
		if( currNode.getAttribute( "isVisible" ) && "false" == currNode.getAttribute( "isVisible" ) )
		{
			return false;
		}
		else if( $un != typeof currNode.style && "none" == currNode.style.display )
		{
			return false;
		}
		
		try
		{
			currNode = currNode.parentNode;
		}
		catch( ex )
		{
			$Log( ex );
		}
	}
	
	return true;
}

function ScheduleManager()
{
	this.editId = "";
	this.editStatus = false;
	this.editTaskDate = null;
	this.editTaskDay = null;
	this.editTaskMonth = null;
	this.editTaskYear = null;
	this.editTaskMinutes = null;
	this.editTaskHour = null;
	this.schedData = {};
	this.scheduledTaskTime = null;
}

ScheduleManager.prototype =
{
	deleteCall : function( callId )
	{
		if( confirm( "Are you sure you want to delete this task?" ) )
		{
			if( "editmode" == callId )
			{
				callId = this.editId;
			}
			
			$X.Post( $X.Url.Call, "DeleteScheduledService", { id : callId }, this.callDeleted.link( this, callId ) ).Send();
			
			this.Refresh();
		}
		else
		{
			$enable( "_scheddelbtn" );
		}
	},
	
	callDeleted : function( cid, res, ok )
	{
		var table = el( "scheduledCallsTable" ),
		idx = this.findRowIndex( table, cid );
		$enable( "_scheddelbtn" );
		
		if( idx >= 0 )
		{
			table.deleteRow( idx );
		}
		
		if( 1 == table.rows.length  )
		{
			el( "scheduledCallsListDiv" ).innerHTML = "You have no scheduled calls or text messages.";
		}
		
		if( this.editStatus )
		{
			this.editStatus = false;
			this.ResetForm();
			this.editId = "";
		}
	},
	
	findRowIndex : function( table, rowId )
	{
		var rows = table.rows;
		
		for( var i = 0, len = rows.length; i < len; ++i )
		{
			if( rows[i].id == rowId )
			{
				return i;
			}
		}
		
		return -1;
	},
	
	formatHourMinute : function( num )
	{
		return 1 == num.length ? "0" + num : num;
	},
	
	setCorrectTime : function( date )
	{
		var dateToDisplay = "",
		realDate = new Date();
		
		realDate.setUTCFullYear( date[0], date[1], date[2] );
		realDate.setUTCHours( date[3], date[4], "0", "0" );
		
		dateToDisplay += this.monthNameLookup( realDate.getMonth() ) +
			" " + realDate.getDate() + ", " +  realDate.getFullYear() + " " + this.formatHourMinute( realDate.getHours().toString() ) +
			":" + this.formatHourMinute( realDate.getMinutes().toString() );
		
		return dateToDisplay;
	},
	
	monthNameLookup : function( monthNum )
	{
		return [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ][ monthNum ];
	},
	
	setAllDates : function()
	{
		var dateCell,
		dateAttribute,
		dateCells = $d.getElementsByName( "dateCell" );
		for( var i = 0, len = dateCells.length; i < len; ++i )
		{
			dateCell = dateCells[i];
			dateAttribute = dateCell.getAttribute( "dateData" );
			dateCell.innerHTML = this.setCorrectTime( eval( dateAttribute ) );
		}
	},
	
	getScheduledCallsList : function()
	{
		var isLoaded = el( "scheduledCallsListDiv" ).load;
		if( !isLoaded )
		{
			this.SetSchedCallLoadingVisible( true );
			var currDate = new Date(),
			clientDate = this.monthNameLookup( currDate.getMonth() )  + " " + currDate.getDate() + " " + currDate.getFullYear() +
				" " + currDate.getHours() + ":" + currDate.getMinutes();
			
			$X.Post( $X.Url.Call, "GetSchedulerList", { offset : currDate.getTimezoneOffset(), date : clientDate }, this.renderCallList.link( this ) ).Send();
		}
	},
	
	renderCallList : function( res, ok )
	{
		this.SetSchedCallLoadingVisible( false );

		setText( "scheduledCallsListDiv", res );
		
		$tog( "scheduledCallsListEmpty", ( el( "scheduledCallsListDiv" ).style.display == "none" ) );
		el( "scheduledCallsListDiv" ).load = "true";
	},
	
	SetSchedCallLoadingVisible : function( visible )
	{
		$tog( "scheduledCallsListLoading", visible );
	},
	
	EditScheduledService : function( taskid, taskDate )
	{
		var months = {
			"Jan":0, "Feb":1, "Mar":2,"Apr":3,"May":4,"Jun":5,"Jul":6,"Aug":7,"Sep":8,"Oct":9,"Nov":10,"Dec":11,
			"M\u00e4r":3, "Okt":9,"Dez":11,   //de
			"Ene":0, "Abr":3, "Ago":7, "Dic":11,  //es
			"Fev":1, "Avr":3, "Mai":4, "Juin":5, "Juil":6, "Aout":7, //fr
			"Gen":0, "Mag":4, "Giu":5, "Lug":6, "Ago":7, "Set":8, "Ott":9, "Nov":10 //it
		},
		month = taskDate.substr( 0, 3 );
		
		this.editTaskDate = taskDate.substr( 0, 6 );
		this.editTaskMonth = months[ month ];
		this.editTaskDay = taskDate.substr( 4, 2 );
		this.editTaskYear = taskDate.substr( 8, 4 );
		this.editTaskHour = taskDate.substr( 13, 2 );
		this.editTaskMinutes = taskDate.substr( 16, 2 ); 
		this.editId = taskid;
		
		$X.Post( $X.Url.Call, "GetScheduledTaskData", { id : taskid }, this.ScheduledServiceUpdateForm.link( this ) ).Send();
	},
	
	ScheduledServiceUpdateForm : function( ret, ok )
	{
		pickerDisplayShow( true );
		
		el( "ScheduleAbsolute" ).checked = true;
		CallMgr.DelayedRelativeType = CallMgr.DelayedTypes.ABS;
		
		var hour = this.editTaskHour,
		minute = Math.floor( this.editTaskMinutes / 5 );
		
		el( "HourData" ).selectedIndex = hour;
		el( "MinuteData" ).selectedIndex = minute;
		
		setCalendar( this.editTaskYear, this.editTaskMonth, this.editTaskDay );
		
		el( "dateData" ).value = this.editTaskDate;
		
		this.schedData = ret;
		this.editStatus = true;
		
		el( "delayedServiceReminder" ).checked = ( "True" == this.schedData.smsReminder );
		el( "delayedServiceSubject" ).value = this.schedData.subject;
		
		//set source number in radio box
		var sourceNumber = this.schedData.source;
		
		if( ( el("mylandline") != null ) && ( el( "mylandline" ).value == sourceNumber ) )
		{
			el( "mylandline" ).checked = true;
		}
		else if( ( el( "myoffice" ) != null ) && ( el( "myoffice" ).value == sourceNumber ) )
		{
			el( "myoffice" ).checked = true;
		}
		else if( ( el( "mymobile" )!= null ) && ( el( "mymobile" ).value == sourceNumber ) )
		{
			el( "mymobile" ).checked = true;
		}
		
		var serviceType = this.schedData.serviceType;
		
		if( 2 == serviceType )
		{
			el( "SmsMessageBox" ).value = this.schedData.message;
			el( "smscontrol" ).style.display = "block";
		}
		
		for( var i = 0, len = this.schedData.numbers.length; i < len; i++ )
		{
		    this.schedData.numbers[i] = $Tel.FromSerialized( this.schedData.numbers[i] );
		}
		
		DestMgr.SetGroup(this.schedData.numbers);
		SmsMgr.Update();
		
		$hide( "priceinfo" );
		$hide( "Console" );
		$show( "editConsole" );
	},
	
	ResetForm : function()
	{
		DestMgr.Reset();
		
		[ "_schedsavebtn", "_scheddelbtn", "_schedbackbtn" ].each( $enable );
		$hide( "smscontrol" );
		$show( "Console" );
		$hide( "editConsole" );
		el( "priceinfo" ).innerHTML = "";
		$show( "priceinfo" );
		el( "delayedServiceSubject" ).value = "";
		
		pickerDisplayShow( false );
		refreshConsoleBtns();
	},
	
	Refresh : function()
	{
		$hide( "scheduledCallsListEmpty" );
		$hide( "scheduledCallsListDiv" );
		el( "scheduledCallsListDiv" ).load = false;
		
		this.getScheduledCallsList();
	}
}

function roundDate()
{
	var date = new Date();
	return new Date( date.getTime() + 60000 * ( 5 - ( date.getMinutes() ) %5 ) );
}

var cdate = roundDate(),
calendarTime = {
	Year	: cdate.getFullYear(),
	month	: cdate.getMonth(),
	Day		: cdate.getDate()
};

function calendarClick(cal)
{
	el('ScheduleAbsolute').checked=true;
    calendarTime.Year = cal.date.getFullYear();   
    calendarTime.month = cal.date.getMonth();
    calendarTime.Day = cal.date.getDate();
}

function setCalendar(year, month, day)
{ 
    calendarTime.Year = year;
    calendarTime.month = month;
    calendarTime.Day = day;
}

function setSchedulingData(mgr)
{
	var months = {
		'Jan': 0, 'Feb' : 1, 'Mar' : 2, 'Apr' : 3, 'May' : 4, 'Jun' : 5, 'Jul' : 6, 'Aug' : 7, 'Sep' : 8, 'Oct' : 9, 'Nov' : 10, 'Dec' : 11,
		'M\u00e4r' : 2, 'Okt' : 9, 'Dez' : 11, //de
		'Ene' : 0, 'Abr' : 3, 'Ago' : 7, 'Dic' : 11,  //es
		'Fev' : 1, 'Avr' : 3, 'Mai' : 4, 'Juin' : 5, 'Juil' : 6, 'Aout' : 7, //fr
		'Gen' : 0, 'Mag' : 4, 'Giu' : 5, 'Lug' : 6, 'Ago' : 7, 'Set' : 8, 'Ott' : 9, 'Nov' : 10 //it
	};
     
    if( el('ScheduleAbsolute').checked == true )
    {
		var schedDate = new Date(),
		hour = el('HourData').value,
		minute = el('MinuteData').value,
		xdate = el('dateData').value.trim(),
		xmonth = months[ xdate.substr(0,3) ],
		xday = xdate.substr(4, 2),
		monthFlag = true;
		
		//this check is instead of calendarTime.Month != '' because in case the month==0 so 0=='' in JS
		if( isNaN(parseInt(calendarTime.month)) )
		{
			monthFlag = false;
		}
		
		if( calendarTime.Year != '' && monthFlag && calendarTime.Day != '' && hour != '' && minute != '' )
        {
			schedDate.setFullYear(parseInt(calendarTime.Year));
			schedDate.setMonth(xmonth);
			
			if( xday.charAt(0) == '0' )
			{
				xday = xday.substring(1);
			}
			
			schedDate.setDate(parseInt(xday));
			schedDate.setHours(parseInt(hour), parseInt(minute), 0, 0);
			mgr.DelayedServiceTime = schedDate.toUTCString();
			mgr.DelayedRelativeType = mgr.DelayedTypes.ABS;
		}
		else
		{
			mgr.DelayedServiceTime = '';
			mgr.DelayedRelativeType = '';
		}
	}
	else if(el('ScheduleRelative').checked == true)
	{
		mgr.DelayedServiceTime = parseInt(el('delayTime').value);
		mgr.DelayedRelativeType = mgr.DelayedTypes.REL;
	}
	mgr.DelayedServiceSubject = el( 'delayedServiceSubject' ).value;
}

function changeDisableStatus(elem, disable)
{
    var elemNodes = elem.childNodes;
    for( var i=0, len = elemNodes.length; i < len; ++i )
    {
        if( typeof( elemNodes[i].type) != 'undefined' )
        {
            if( elemNodes[i].type != 'radio' )
            {
                try
                {
                    elemNodes[i].disabled = disable;
                }
                catch(ex)
                {
                }
            }
        }
    }
}

function validateTime( e, timePart )
{
	var target = e.srcElement || e.target,
	isValid = false;
	
	if( /^\d+$/.test( target.value ) )
	{
		var val = parseInt( target.value );
		if( timePart == 'Hour' )
		{
			if(val >= 0 && val <=23)
			{
				isValid = true;
			}
		}
		else if(timePart == 'Minute')
		{
			if(val >= 0 && val <=59)
			{
				isValid = true;
			}
		}
	}
	
	if( !isValid )
	{
		target.value = '';
	}
}

function pickerDisplay()
{
    var picker = el(schedPickerClId);
    if ("none" == picker.style.display.trim() )
    {
		// handle scheduled service
		CallMgr.CallType = CallMgr.CallTypes.SCHED;
		$show( picker );

		el("ScheduledCallTitle").style.backgroundImage = 'url(../images/icons/minus.gif)';
		
		el('UpperBoxLine').style.display = 'inline'; // render scheduled call
		
		var isCall = !isVisible('smscontrol');
		
		if (isCall == true)
		{
			el('CallBtns').style.display = 'inline'; // render CALL buttons
			$hide('SMSBtns'); // hide SMS buttons
			el('ScheduledCallBtns').style.display = 'inline'; // render scheduled call
			$hide('InstantCallBtns'); // hide instant call
		}
		else
		{
			el('SMSBtns').style.display = 'inline'; // render SMS buttons
			$hide('CallBtns'); // hide CALL buttons
			el('ScheduledSMSBtns').style.display = 'inline'; // render scheduled SMS
			$hide('InstantSMSBtns'); // hide instant SMS
		}
	}
	else
	{
		// handle instant service
		
		$hide( picker );
		el("ScheduledCallTitle").style.backgroundImage = 'url(../images/icons/add.gif)';
		$hide('UpperBoxLine'); // hide instant call
		
		CallMgr.CallType = CallMgr.CallTypes.DEF;
		
		if( isVisible('smscontrol') )
		{
			el('SMSBtns').style.display = 'inline'; // render SMS buttons
			$hide('CallBtns'); // hide CALL buttons
			el('InstantSMSBtns').style.display = 'inline'; // render instant SMS
			$hide('ScheduledSMSBtns'); // hide scheduled SMS
		}
		else
		{
			el('CallBtns').style.display = 'inline'; // render CALL buttons
			$hide('SMSBtns'); // hide SMS buttons
			el('InstantCallBtns').style.display = 'inline'; // render instant call
			$hide('ScheduledCallBtns'); // hide instant call
		}
	}
	
	CallMgr.Changed = true;
	CallMgr.CalcRate();
}

function pickerDisplayShow( flag )
{
	var picker = el(schedPickerClId);
	
	if( !isPickerVisible() && flag )
	{
		// handle scheduled service
		
		CallMgr.CallType = CallMgr.CallTypes.SCHED;
		CallMgr.Changed = true;
		
		picker.style.display = '';
		el("ScheduledCallTitle").style.backgroundImage = 'url(../images/icons/minus.gif)';
		
		if( isVisible('smscontrol') )
		{
			el('SMSBtns').style.display = 'inline'; // render SMS buttons
			$hide('CallBtns'); // hide CALL buttons
			el('ScheduledSMSBtns').style.display = 'inline'; // render scheduled SMS
			$hide('InstantSMSBtns'); // hide instant SMS
		}
		else
		{
			el('CallBtns').style.display = 'inline'; // render CALL buttons
			$hide('SMSBtns'); // hide SMS buttons
			el('ScheduledCallBtns').style.display = 'inline'; // render scheduled call
			$hide('InstantCallBtns'); // hide instant call
		}
	}
	else if( isPickerVisible() && !flag )
	{
		// handle instant service
		
		CallMgr.CallType = CallMgr.CallTypes.DEF;
		CallMgr.Changed = true;
		
		$hide( picker );
		el( "ScheduledCallTitle" ).style.backgroundImage = 'url(../images/icons/add.gif)';
		
		if( isVisible( 'smscontrol' ) )
		{
			el('SMSBtns').style.display = 'inline'; // render SMS buttons
            $hide('CallBtns'); // hide CALL buttons
            el('InstantSMSBtns').style.display = 'inline'; // render instant SMS
            $hide('ScheduledSMSBtns'); // hide scheduled SMS
		}
		else
		{
			el('CallBtns').style.display = 'inline'; // render CALL buttons
			$hide('SMSBtns'); // hide SMS buttons
			el('InstantCallBtns').style.display = 'inline'; // render instant call
			$hide('ScheduledCallBtns'); // hide instant call
		}
	}
}

