//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections;

namespace CommunityServer.Components
{
	/// <summary>
	/// Contains base methods for manaing groups. Look for application specific
	/// implementations for app related objects
	/// </summary>
	public class Groups
	{
		private Groups()
		{
		}

        /// <summary>
        /// Adds a new Group to the datastore
        /// </summary>
        /// <param name="group"></param>
        /// <returns></returns>
        public static int AddGroup(Group group) 
        {
			CSEvents.BeforeGroup(group,ObjectState.Create,group.ApplicationType);

            // Create Instance of the CommonDataProvider
            CommonDataProvider dp = CommonDataProvider.Instance();
            group.GroupID =  dp.CreateUpdateDeleteGroup(group, DataProviderAction.Create);

            CSContext context = CSContext.Current;
            EventLogEntry entry = new EventLogEntry();
            entry.Message = string.Format("Group {0}({1} in application {2} was created by {3}", group.Name, group.GroupID,group.ApplicationType, context.User.Username);
            entry.Category = "Data";
            entry.EntryID = 205;
            entry.SettingsID = context.SettingsID;
            EventLogs.Write(entry);

			CSEvents.AfterGroup(group,ObjectState.Create,group.ApplicationType);

			return group.GroupID;
        }

        /// <summary>
        /// Updates an existing Group in the datastore
        /// </summary>
        /// <param name="group"></param>
        public static void UpdateGroup(Group group) 
        {
			CSEvents.BeforeGroup(group,ObjectState.Update,group.ApplicationType);

            // Create Instance of the IDataProvider
            CommonDataProvider dp = CommonDataProvider.Instance();
            dp.CreateUpdateDeleteGroup(group, DataProviderAction.Update);

			CSEvents.AfterGroup(group,ObjectState.Update,group.ApplicationType);
        }

        /// <summary>
        /// Deletes the specified Group
        /// </summary>
        /// <param name="g"></param>
        public static void DeleteGroup (Group g) 
        {
            try 
            {
				CSEvents.BeforeGroup(g,ObjectState.Delete,g.ApplicationType);

                CommonDataProvider dp = CommonDataProvider.Instance();
                dp.CreateUpdateDeleteGroup(g, DataProviderAction.Delete);

                EventLogs.Write(string.Format("Group {0}({1}) was deleted", g.Name,g.GroupID),"Data",206,EventType.Information, CSContext.Current.SettingsID);

				CSEvents.AfterGroup(g,ObjectState.Delete,g.ApplicationType);
            } 
            catch (CSException exception) 
            {
                if (exception.ExceptionType == CSExceptionType.GroupNotFound)
                    return;
                else 
                    throw exception;
            }

        }

        public static void ReOrder(int groupID, int index)
        {
            CommonDataProvider dp = CommonDataProvider.Instance();
            dp.ReOrderGroup(groupID,index);
        }


		public static Hashtable HideUsersGroups (Hashtable groups, User user) 
		{

			int[] hiddenGroups = user.GroupIgnoreFilter;
			
			for (int i = 0; i < hiddenGroups.Length; i++) 
			{

				// Convert the value to an integer if we fail ignore
				//
				try 
				{
					int groupID = hiddenGroups[i];

					

					Group g = groups[groupID] as Group;

					if (g != null)
						groups.Remove(groupID);
				} 
				catch {}

			}

			return groups;
		}

        /// <summary>
        /// Provides logic for hidding selected groups
        /// </summary>
        /// <param name="groups"></param>
        /// <returns></returns>
        public static Hashtable HideGroups (Hashtable groups) 
        {

            //Find User once
            User user = CSContext.Current.User;

            //If user has disabled it, just return
            if( !user.EnableCollapsingPanels) 
                return groups;

         
            //Still here? Look for groups to hide

            // Process any hidden forums for this user. When a forum group's
            // HideForum property is set to true, the forum group is shown
            // but the contained forums are not displayed
            //
            string[] hiddenGroups = user.GetUserCookie().HiddenGroups;

            Group g = null;
            for (int i = 0; i < hiddenGroups.Length; i++) 
            {

                // Convert the value to an integer if we fail ignore
                //
                try 
                {
                    int groupID = Convert.ToInt32( hiddenGroups[i] );

                    // Look in the forum group hashtable and hide the forum group
                    //
                    g = groups[groupID] as Group;

                    if (g != null)
                        g.HideSections = true;
                } 
                catch {}

            }

            return groups;
        }

		#region Auto Naming

		/// <summary>
		/// Searches the list for the next available name based on the pattern string
		/// </summary>
		public static string NextGroupName(ArrayList groups, string baseName)
		{
			string newname = baseName;
			if(!HasGroup(groups, newname))
				return newname;
			
			int i = 2;
			newname = string.Concat(baseName, " ({0})");
			while(HasGroup(groups, string.Format(newname,i)))
				i++;

			return string.Format(newname,i);
		}

		/// <summary>
		/// Checks to see if a group with that name already exists in the list
		/// </summary>
		public static bool HasGroup(ArrayList groups, string name)
		{
			foreach(Group gr in groups)
				if(gr.Name.ToLower() == name.ToLower())
					return true;

			return false;
		}

		#endregion

	}
}
