/*
* Copyright (C) 2007 Eskil Bylund
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using DCSharp.Backend.Connections;
namespace DCSharp
{
public class UserEventArgs : EventArgs
{
private User user;
public UserEventArgs(User user)
{
this.user = user;
}
public User User
{
get { return user; }
}
}
///
/// A class representing a unique user.
///
///
/// This class represents a single unique user, identified by a uid.
///
/// A user can be online on multiple hubs. The hubs can be enumerated on
/// using EnumerateOnlineHubs.
///
public class User
{
private static Dictionary users = new Dictionary();
public event EventHandler OnlineOnHub;
public event EventHandler OfflineOnHub;
public event EventHandler OnlineChanged;
private List hubs;
private Uid uid;
private string nick;
private bool online;
private User(Uid uid, string nick)
{
if (nick == null)
{
throw new ArgumentNullException("nick");
}
this.uid = uid;
this.nick = nick;
hubs = new List();
}
#region Properties
///
/// Gets the Uid of the user.
///
/// The Uid of the user.
public Uid Uid
{
get { return uid; }
//set { uid = value; }
}
///
/// Gets the nickname of the user.
///
/// The nickname of the user.
public string Nick
{
get { return nick; }
//set { nick = value; }
}
///
/// Gets whether or not the user is online.
///
/// Whether or not the user is online.
public bool IsOnline
{
get { return online; }
private set
{
online = value;
OnOnlineChanged();
}
}
internal object SyncRoot
{
get { return hubs; }
}
#endregion
#region Methods
///
/// Creates or returns the user with the specified uid.
///
/// The uid of the user.
/// The nickname of the user.
/// The user with the specified uid.
internal static User Create(Uid uid, string name)
{
lock (users)
{
User user = Get(uid);
if (user == null)
{
user = new User(uid, name);
users[uid] = new WeakReference(user);
}
return user;
}
}
///
/// Returns the user with the specified uid.
///
/// The uid of the user.
/// The user with the specified uid.
internal static User Get(Uid uid)
{
lock (users)
{
User user = null;
WeakReference reference;
if (users.TryGetValue(uid, out reference))
{
user = (User)reference.Target;
}
return user;
}
}
///
/// Adds a specific hub to the list of online hubs.
///
/// The hub the user is online on.
internal void AddHub(HubConnection hub)
{
if (hub == null)
{
throw new ArgumentNullException("hub");
}
bool emitOnline = false;
lock (hubs)
{
if (hubs.Contains(hub))
{
return;
}
hubs.Add(hub);
emitOnline = hubs.Count == 1;
}
if (emitOnline)
{
IsOnline = true;
}
OnOnlineOnHub(hub);
}
///
/// Removes a specific hub from the list of online hubs.
///
/// The hub the user is no longer online on.
internal void RemoveHub(HubConnection hub)
{
if (hub == null)
{
throw new ArgumentNullException("hub");
}
bool emitOffline = false;
lock (hubs)
{
if (!hubs.Contains(hub))
{
return;
}
hubs.Remove(hub);
emitOffline = hubs.Count == 0;
}
if (emitOffline)
{
IsOnline = false;
}
OnOfflineOnHub(hub);
}
///
/// Checks if the user is online on a specific hub.
///
/// The hub to check.
/// True if the user is online on the hub; otherwise, false.
public bool IsOnlineOnHub(HubConnection hub)
{
lock (hubs)
{
return hubs.Contains(hub);
}
}
public void EnumerateOnlineHubs(Action action)
{
lock (hubs)
{
foreach (HubConnection hub in hubs)
{
action(hub);
}
}
}
public override bool Equals(object a)
{
return this == a;
}
public override int GetHashCode()
{
return uid.GetHashCode() << 1;
}
public override string ToString()
{
return String.Format("{0} ({1})", nick, uid);
}
///
/// Emits the OnlineChanged event.
///
protected void OnOnlineChanged()
{
if (OnlineChanged != null)
{
OnlineChanged(this, EventArgs.Empty);
}
}
///
/// Emits the OnlineOnHub event.
///
protected void OnOnlineOnHub(HubConnection hub)
{
if (OnlineOnHub != null)
{
OnlineOnHub(this, new ConnectionEventArgs(hub));
}
}
///
/// Emits the OfflineOnHub event.
///
protected void OnOfflineOnHub(HubConnection hub)
{
if (OfflineOnHub != null)
{
OfflineOnHub(this, new ConnectionEventArgs(hub));
}
}
#endregion
}
}