using System;
using DarkStrideToolbox;


namespace DarkStrideToolbox
{
	public class IdentificationBuoy : MarshalByRefObject
	{
		#region Properties
		private DSSortedList m_oKnownUsers = new DSSortedList();
		private DSSortedList m_oPendingUsers = new DSSortedList();
		private User m_oMyUser = null;
		#endregion

		#region Events
		public event EventHandler UpdateUserListEvent;

		protected void RaiseUpdateUserList()
		{
			EventArgs oArgs = null;
			try
			{
				if( UpdateUserListEvent != null )
				{
					oArgs = new EventArgs();
					UpdateUserListEvent( null, oArgs );
				}
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( oEx );
			}
		}

		#endregion       		


		public IdentificationBuoy()
		{
		}

		public void UpdateUserList( DSSortedList oTheirUsers,User oUserUpdatingMe )
		{
			User oOldPendingUser = null;
			User oNewPendingUser = null;
			User oUser = null;


			try
			{
				lock( m_oPendingUsers )
				{
					for( int i=0 ; i<oTheirUsers.Count ; i++ )
					{
						oNewPendingUser = (User)oTheirUsers.GetByIndex( i );

						//Make sure we don't dupe!
						if( m_oPendingUsers.ContainsKey( oTheirUsers.GetKey( i ) ) == true )
						{
							oOldPendingUser = (User)m_oPendingUsers.GetByKey( oTheirUsers.GetKey( i ) );						

							if( oOldPendingUser.TimeOfLatestInfo < oNewPendingUser.TimeOfLatestInfo )
							{
								m_oPendingUsers.Remove( oOldPendingUser.GUID );
							}
							else
							{
								oNewPendingUser = null;
							}
						}
					
						//Is this user already in our collection?
						if( oNewPendingUser != null )
						{
							m_oPendingUsers.Add( oNewPendingUser.GUID,oNewPendingUser );
						}
					}
				}

				//Update my information about the updater
				oUser = (User)m_oKnownUsers.GetByKey( oUserUpdatingMe.GUID );
				if( oUser != null )
				{
					oUser.UpdateUserFrom( oUserUpdatingMe );
				}

				RaiseUpdateUserList();
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( oEx );
			}
		}

		public void RemovePendingUser( string sGUID )
		{
			m_oPendingUsers.Remove( sGUID );
		}


		public long GetNumberOfUsersofType( enumStatus nType )
		{
			User oKnownUser = null;
			long nCount = 0;


			for( int nLoopUserIndex=0 ; nLoopUserIndex<m_oKnownUsers.Count ; nLoopUserIndex++ )
			{
				oKnownUser = (User)m_oKnownUsers.GetByIndex( nLoopUserIndex );

				if( oKnownUser.Status == nType )
				{
					nCount++;
				}
			}


			return( nCount );
		}

		public void AddUser( User oUser )
		{
			if( m_oKnownUsers.ContainsKey( oUser.GUID ) == true )
			{
				m_oKnownUsers.Remove( oUser.GUID );
			}
			m_oKnownUsers.Add( oUser.GUID,oUser );
		}



		#region Properties
		public DSSortedList Users
		{
			get
			{
				return( m_oKnownUsers );
			}
		}
		public DSSortedList PendingUsers
		{
			get
			{
				return( m_oPendingUsers );
			}
			set
			{
				m_oPendingUsers = value;
			}
		}
		public User MyUser
		{
			get
			{
				return( m_oMyUser );
			}
			set
			{
				m_oMyUser = value;
			}
		}
		#endregion
	}
}