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

using System;
using CommunityServer.Components;
using Telligent.CommunityServer.MetadataExtractor.Exif;

namespace CommunityServer.Galleries.Components
{
	/// <summary>
	/// This class defines the properties that are used for Galleries.  It inherits from the base class <see cref="CommunityServer.Components.Section"/>.
	/// </summary>
	public class Gallery : CommunityServer.Components.Section
	{

		#region Public

		public bool EnableRss
		{
			get {  return GetBool("EnableRss",true); }
			set{ SetExtendedAttribute("EnableRss",value.ToString()); }
		}

		public bool EnableAbout
		{
			get {  return GetBool("EnableAbout",true); }
			set{ SetExtendedAttribute("EnableAbout",value.ToString()); }
		}

		public bool EnableContact //Not enabled in the admin area or skin
		{
			get {  return GetBool("EnableContact",false); }
			set{ SetExtendedAttribute("EnableContact",value.ToString()); }
		}

		public bool EnableTrackbacks
		{
			get{return GetBool("EnableTrackbacks", true);}
			set{ SetExtendedAttribute("EnableTrackbacks",value.ToString()); }
		}

		#region Post Globals/Overrides


		public bool EnableTrackbacksOverride
		{
			get{return GetBool("EnableTrackbacksOverride", true);}
			set{ SetExtendedAttribute("EnableTrackbacksOverride",value.ToString()); }
		}

		public bool EnableCommentsOverride
		{
			get {  return GetBool("EnableCommentsOverride",true); }
			set{ SetExtendedAttribute("EnableCommentsOverride",value.ToString()); }
		}

		public bool EnableRssCommentsOverride
		{
			get {return GetBool("EnableRssCommentsOverride", false); }
			set {SetExtendedAttribute("EnableRssCommentsOverride", value.ToString()); }
		}

		public bool EnableRatingsOverride
		{
			get{return GetBool("EnableRatingsOverride", true);}
			set{ SetExtendedAttribute("EnableRatingsOverride",value.ToString()); }
		}
		
		public bool EnableOrderPrintsOverride
		{
			get{return GetBool("EnableOrderPrintsOverride", true);}
			set{ SetExtendedAttribute("EnableOrderPrintsOverride",value.ToString()); }
		}

		public CommentModerationType ModerationTypeOverride
		{
			get
			{

				return (CommentModerationType)Enum.Parse(typeof(CommentModerationType),GetString("ModerationTypeOverride","Ignore"),false);
				
			}
			set
			{
				SetExtendedAttribute("ModerationTypeOverride",value.ToString());
			}
		
		}

		#endregion

		#region Default Settings

		public CommentModerationType ModerationTypeDefault
		{
			//We need to support previous .Text configuration options. 
			//If IsModerated = true, we will return CommentModerationType.All since this was the same .Text behavior
			//If a user updates this property, we will set IsModerated to false, which will be an indication that we will 
			//no longer need to honor the .Text concept. 

			get
			{

				if(IsModerated)
					return CommentModerationType.All;

				return (CommentModerationType)Enum.Parse(typeof(CommentModerationType),GetString("CommentModerationType","None"),false);
				
			}
			set
			{
				this.IsModerated = false;
				SetExtendedAttribute("CommentModerationType",value.ToString());
			}
		
		}

		public bool EnableCommentsDefault
		{
			get {  return GetBool("EnableComments",true); }
			set{ SetExtendedAttribute("EnableComments",value.ToString()); }
		}

		public bool EnableRssCommentsDefault
		{
			get {return GetBool("EnableRssComments", false); }
			set {SetExtendedAttribute("EnableRssComments", value.ToString()); }
		}

		public bool EnableRatingsDefault
		{
			get{return GetBool("EnableRatings", true);}
			set{ SetExtendedAttribute("EnableRatings",value.ToString()); }
		}

		public bool EnableTrackbacksDefault
		{
			get{return GetBool("EnableTrackbacks", true);}
			set{ SetExtendedAttribute("EnableTrackbacks",value.ToString()); }
		}


		public bool EnableCommunityParticipationDefault
		{
			get{ return GetDefaultPostConfig(GalleryPostConfig.IsCommunityAggregated);}
			set{  SetDefaultPostConfig(GalleryPostConfig.IsCommunityAggregated,value); }
		}

		public bool EnablePostAggregationDefault
		{
			get{ return GetDefaultPostConfig(GalleryPostConfig.IsAggregated);}
			set{  SetDefaultPostConfig(GalleryPostConfig.IsAggregated,value); }
		}

		public bool SyndicateExcerptDefault
		{
			get{ return GetDefaultPostConfig(GalleryPostConfig.SyndicateExcerpt);}
			set{  SetDefaultPostConfig(GalleryPostConfig.SyndicateExcerpt,value); }
		}

		public GalleryPostConfig DefaultPostConfig
		{
			get{ return (GalleryPostConfig) GetInt("DefaultPostConfig", 3); }
			set { SetExtendedAttribute("DefaultPostConfig", ((int)value).ToString());}
		}

		protected void SetDefaultPostConfig(GalleryPostConfig gpc, bool isSelected)
		{
			DefaultPostConfig = PostConfigHelper.SetPostConfig(DefaultPostConfig,gpc,isSelected);
		}

  
		protected bool GetDefaultPostConfig(GalleryPostConfig gpc)
		{
			return PostConfigHelper.IsPostConfigSelected(DefaultPostConfig,gpc);
		}
		#endregion

		public int CommentExpirationDays
		{
			get
			{
				string i = GetExtendedAttribute("ced");
				if(i == null || i.Trim().Length == 0)
					return 999999;

				return Int32.Parse(i);
			}
			set{ SetExtendedAttribute("ced",value.ToString()); }
		}

		public string AboutTitle
		{
			get{return GetString("aboutTitle", "About " + this.Name);}
			set{SetExtendedAttribute("aboutTitle", value);}
		}

		public string AboutDescription
		{
			get{return GetExtendedAttribute("aboutDescription");}
			set{SetExtendedAttribute("aboutDescription", value);}
		}

		public bool HasAbout
		{
			get{ return !Globals.IsNullorEmpty(AboutTitle) || !Globals.IsNullorEmpty(AboutDescription); }
		}

		#endregion

		#region Permissions

		public override PermissionBase DefaultRolePermission
		{
			get
			{
				return new GalleryPermission();
			}
		}

		public override AccessCheckDelegate AccessCheck
		{
			get
			{
				return new AccessCheckDelegate(GalleryPermission.AccessCheck);
			}
		}

		public override ValidatePermissionsDelegate ValidatePermissions
		{
			get
			{
				return new ValidatePermissionsDelegate(GalleryPermission.Validate);
			}
		}

		public override bool IsPrivate
		{
			get
			{
				User user = Users.GetAnonymousUser(true);
				if(user != null)
				{
					return !Permissions.ValidatePermissions(this,Permission.View,user);
				}
				return true;
			}

		}

		#endregion

		#region Quotas

		/// <summary>
		/// This property defines the number of images that can be stored in a Gallery
		/// </summary>
		public int ImageQuota
		{
			get
			{
				string val = GetExtendedAttribute( "ImageQuota" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return -1;
			}
			set
			{
				if(value < 0)
					SetExtendedAttribute( "ImageQuota", "-1" );
				else
					SetExtendedAttribute( "ImageQuota", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the amount of diskspace that can be used by a Gallery
		/// </summary>
		public int DiskQuota
		{
			get
			{
				string val = GetExtendedAttribute( "DiskQuota" );
				try
				{
					if(val != string.Empty)
						return int.Parse(val);
				}
				catch{}
					return -1;
			}
			set
			{
				if(value < 0)
					SetExtendedAttribute( "DiskQuota", "-1" );
				else
					SetExtendedAttribute( "DiskQuota", value.ToString() );
			}
		}
		#endregion

        #region ExifProperty
        private string[] displayExifProperties = null;


        /// <summary>
        /// This property defines the different <see cref="ExifProperty"/> attributes that are displayed when viewing a picture
        /// in this <see cref="Gallery"/>
        /// </summary>
        public string[] DisplayExifProperties
        {
            get
            {
                if (displayExifProperties == null)
                {
                    if (GetExtendedAttribute("DisplayExifProperties") != string.Empty && GetExtendedAttribute("DisplayExifProperties").IndexOf(":") != -1)
                    {
                        displayExifProperties = GetExtendedAttribute("DisplayExifProperties").Split(',');
                    }
                    else
                    {
                        displayExifProperties = new string[6];
                        displayExifProperties[0] = typeof(ExifDirectory).FullName + ":" + ExifDirectory.TAG_MODEL;
                        displayExifProperties[1] = typeof(ExifDirectory).FullName + ":" + ExifDirectory.TAG_DATETIME_ORIGINAL;
                        displayExifProperties[2] = typeof(ExifDirectory).FullName + ":" + ExifDirectory.TAG_EXPOSURE_TIME;
                        displayExifProperties[3] = typeof(ExifDirectory).FullName + ":" + ExifDirectory.TAG_APERTURE;
                        displayExifProperties[4] = typeof(ExifDirectory).FullName + ":" + ExifDirectory.TAG_FOCAL_LENGTH;
                        displayExifProperties[5] = typeof(ExifDirectory).FullName + ":" + ExifDirectory.TAG_FLASH;
                    }
                }
                return displayExifProperties;
            }
            set
            {
                displayExifProperties = value;
                SetExtendedAttribute("DisplayExifProperties", string.Join(",", value));
            }
        }

        #endregion

		#region Extended Attributes

		/// <summary>
		/// This property defines the number of columns that are displayed when viewing a listing of <see cref="PostCategory"/> items
		/// </summary>
		public int CategoryListingColumns
		{
			get
			{
				string val = GetExtendedAttribute( "CategoryListingColumns" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return 2;
			}
			set
			{
				if(value < 1)
					SetExtendedAttribute( "CategoryListingColumns", "1" );
				else
					SetExtendedAttribute( "CategoryListingColumns", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the number of rows that are displayed when viewing a listing of <see cref="PostCategory"/> items
		/// </summary>
		public int CategoryListingRows
		{
			get
			{
				string val = GetExtendedAttribute( "CategoryListingRows" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return 3;
			}
			set
			{
				if(value < 1)
					SetExtendedAttribute( "CategoryListingRows", "1" );
				else
					SetExtendedAttribute( "CategoryListingRows", value.ToString() );
			}
		}


		/// <summary>
		/// This property defines the number of columns that are displayed when viewing a listing of <see cref="GalleryPost"/> items
		/// </summary>
		public int PictureListingColumns
		{
			get
			{
				string val = GetExtendedAttribute( "PictureListingColumns" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return 4;
			}
			set
			{
				if(value < 1)
					SetExtendedAttribute( "PictureListingColumns", "1" );
				else
					SetExtendedAttribute( "PictureListingColumns", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the number of rows that are displayed when viewing a listing of <see cref="GalleryPost"/> items
		/// </summary>
		public int PictureListingRows
		{
			get
			{
				string val = GetExtendedAttribute( "PictureListingRows" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return 4;
			}
			set
			{
				if(value < 1)
					SetExtendedAttribute( "PictureListingRows", "1" );
				else
					SetExtendedAttribute( "PictureListingRows", value.ToString() );
			}
		}

		public GalleryThreadSortBy ThreadSortBy
		{
			get
			{
				string val = GetExtendedAttribute( "ThreadSortBy" );
				if(val != string.Empty)
					return (GalleryThreadSortBy)Enum.Parse(typeof(GalleryThreadSortBy), val);
				else
					return GalleryThreadSortBy.PictureDate;
			}
			set
			{
				SetExtendedAttribute( "ThreadSortBy", value.ToString() );
			}
		}

		public SortOrder ThreadSortOrder
		{
			get
			{
				string val = GetExtendedAttribute( "ThreadSortOrder" );
				if(val != string.Empty)
					return (SortOrder)Enum.Parse(typeof(SortOrder), val);
				else
					return CommunityServer.Components.SortOrder.Ascending;
			}
			set
			{
				SetExtendedAttribute( "ThreadSortOrder", value.ToString() );
			}
		}
		/// <summary>
		/// This property defines the delay in seconds of the time between image changes in slideshows
		/// </summary>
		public int SlideshowDelay
		{
			get
			{
				string val = GetExtendedAttribute( "SlideshowDelay" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return 5;
			}
			set { SetExtendedAttribute( "SlideshowDelay", value.ToString() ); }
		}

		public CategorizationType CategorizationType
		{
			get
			{
				string val = GetExtendedAttribute("CategorizationType");
				if (val != string.Empty)
					return (CategorizationType) int.Parse(val);
				else
					return CategorizationType.Tag;
			}
			set
			{
				SetExtendedAttribute("CategorizationType", ((int) value).ToString());
			}
		}

		#endregion

		#region Feature Settings

		public bool EnableComments
		{
			get {return GetBool( "EnableComments", true );}
			set { SetExtendedAttribute( "EnableComments", value.ToString() ); }
		}

		public bool EnableRatings
		{
			get {return GetBool( "EnableRatings", true );}
			set { SetExtendedAttribute( "EnableRatings", value.ToString() ); }
		}

		public bool EnableExif
		{
			get {return GetBool( "EnableExif", true );}
			set { SetExtendedAttribute( "EnableExif", value.ToString() ); }
		}

		public bool EnableOrderPrints
		{
			get {return GetBool( "EnableOrderPrints", true );}
			set { SetExtendedAttribute( "EnableOrderPrints", value.ToString() ); }
		}

		#endregion

		#region Image Settings

		public bool EnableSecondaryThumbnail
		{
			get
			{
				string val = GetExtendedAttribute( "EnableSecondaryThumbnail" );
				if(val != string.Empty)
					return bool.Parse(val);
				else
					return true;
			}
			set { SetExtendedAttribute( "EnableSecondaryThumbnail", value.ToString() ); }
		}

		public bool EnableHighlightThumbnail
		{
			get
			{
				string val = GetExtendedAttribute( "EnableHighlightThumbnail" );
				if(val != string.Empty)
					return bool.Parse(val);
				else
					return true;
			}
			set { SetExtendedAttribute( "EnableHighlightThumbnail", value.ToString() ); }
		}


		
		#region Thumbnail

		public GalleryImageSettings GetThumbnailSettings()
		{
			GalleryImageSettings thumbnail = new GalleryImageSettings(GalleryImageType.Thumbnail, ThumbnailX,ThumbnailY,ThumbnailQuality);

			thumbnail.Brightness = ThumbnailBrightness;

			return thumbnail;

		}

		/// <summary>
		/// This property defines the width of thumbnail images
		/// </summary>
		public int ThumbnailX
		{
			get
			{
				string val = GetExtendedAttribute( "ThumbnailX" );
				if(val != string.Empty)
				{
					int iVal = int.Parse(val); 
					if(HasMaxX && MaxX <= iVal)
						return MaxX;
					else
						return iVal;
				}
				else
				{
					int iVal = 100; 
					if(HasMaxX && MaxX <= iVal)
						return MaxX;
					else
						return iVal;
				}
			}
			set
			{
				if(HasMaxX && MaxX >= value  || value <= 0)
					SetExtendedAttribute( "ThumbnailX", null );
				else
					SetExtendedAttribute( "ThumbnailX", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the height of thumbnail images
		/// </summary>
		public int ThumbnailY
		{
			get
			{
				string val = GetExtendedAttribute( "ThumbnailY" );
				if(val != string.Empty)
				{
					int iVal = int.Parse(val); 
					if(HasMaxY && MaxY <= iVal)
						return MaxY;
					else
						return iVal;
				}
				else
				{
					int iVal = 87; 
					if(HasMaxY && MaxY <= iVal)
						return MaxY;
					else
						return iVal;
				}
			}
			set
			{
				if(HasMaxY && MaxY >= value  || value <= 0)
					SetExtendedAttribute( "ThumbnailY", null );
				else
					SetExtendedAttribute( "ThumbnailY", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the quality percentage of thumbnail images
		/// </summary>
		public int ThumbnailQuality
		{
			get
			{
				string val = GetExtendedAttribute( "ThumbnailQuality" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return Quality;
			}
			set
			{
				if(value == Quality)
					SetExtendedAttribute( "ThumbnailQuality", null );
				else
					SetExtendedAttribute( "ThumbnailQuality", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the brightness of thumbnail images (0-200, -1 to disable changing the brightness)
		/// </summary>
		public int ThumbnailBrightness
		{
			get
			{
				string val = GetExtendedAttribute( "ThumbnailBrightness" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return -1;
			}
			set
			{
				if(value < 0)
					SetExtendedAttribute( "ThumbnailBrightness", "-1" );
				else if(value > 100)
					SetExtendedAttribute( "ThumbnailBrightness", "100" );
				else
					SetExtendedAttribute( "ThumbnailBrightness", value.ToString() );
			}
		}

		#endregion

		#region SecondaryThumbnail

		public GalleryImageSettings GetSecondaryThumbnailSettings()
		{
			GalleryImageSettings secondaryThumbnail = new GalleryImageSettings(GalleryImageType.SecondaryThumbnail,SecondaryThumbnailX, SecondaryThumbnailY,SecondaryThumbnailQuality);

			return secondaryThumbnail;

		}

		/// <summary>
		/// This property defines the width of large thumbnails
		/// </summary>
		public int SecondaryThumbnailX
		{
			get
			{
				string val = GetExtendedAttribute( "SecondaryThumbnailX" );
				if(val != string.Empty)
				{
					int iVal = int.Parse(val); 
					if(HasMaxX && MaxX <= iVal)
						return MaxX;
					else
						return iVal;
				}
				else
				{
					int iVal = 160; 
					if(HasMaxX && MaxX <= iVal)
						return MaxX;
					else
						return iVal;
				}
			}
			set
			{
				if(HasMaxX && MaxX >= value  || value <= 0)
					SetExtendedAttribute( "SecondaryThumbnailX", null );
				else
					SetExtendedAttribute( "SecondaryThumbnailX", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the height of large thumbnails
		/// </summary>
		public int SecondaryThumbnailY
		{
			get
			{
				string val = GetExtendedAttribute( "SecondaryThumbnailY" );
				if(val != string.Empty)
				{
					int iVal = int.Parse(val); 
					if(HasMaxY && MaxY <= iVal)
						return MaxY;
					else
						return iVal;
				}
				else
				{
					int iVal = 140; 
					if(HasMaxY && MaxY <= iVal)
						return MaxY;
					else
						return iVal;
				}
			}
			set
			{
				if(HasMaxY && MaxY >= value  || value <= 0)
					SetExtendedAttribute( "SecondaryThumbnailY", null );
				else
					SetExtendedAttribute( "SecondaryThumbnailY", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the quality percentage for large thumbnail images
		/// </summary>
		public int SecondaryThumbnailQuality
		{
			get
			{
				string val = GetExtendedAttribute( "SecondaryThumbnailQuality" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return Quality;
			}
			set
			{
				if(value == Quality)
					SetExtendedAttribute( "SecondaryThumbnailQuality", null );
				else
					SetExtendedAttribute( "SecondaryThumbnailQuality", value.ToString() );
			}
		}

		#endregion

		#region PictureDetails

		public GalleryImageSettings GetPictureDetailsSettings()
		{
			GalleryImageSettings pictureDetails = new GalleryImageSettings(GalleryImageType.Details, PictureDetailsX, PictureDetailsY, PictureDetailsQuality);

			return pictureDetails;
	
		}

		/// <summary>
		/// This property defines the width of the image shown on the picture details screen
		/// </summary>
		public int PictureDetailsX
		{
			get
			{
				string val = GetExtendedAttribute( "PictureDetailsX" );
				if(val != string.Empty)
				{
					int iVal = int.Parse(val); 
					if(HasMaxX && MaxX <= iVal)
						return MaxX;
					else
						return iVal;
				}
				else
				{
					int iVal = 500; 
					if(HasMaxX && MaxX <= iVal)
						return MaxX;
					else
						return iVal;
				}
			}
			set
			{
				if(HasMaxX && MaxX >= value  || value <= 0)
					SetExtendedAttribute( "PictureDetailsX", null );
				else
					SetExtendedAttribute( "PictureDetailsX", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the height of the image shown on the picture details screen
		/// </summary>
		public int PictureDetailsY
		{
			get
			{
				string val = GetExtendedAttribute( "PictureDetailsY" );
				if(val != string.Empty)
				{
					int iVal = int.Parse(val); 
					if(HasMaxY && MaxY <= iVal)
						return MaxY;
					else
						return iVal;
				}
				else
				{
					int iVal = 375; 
					if(HasMaxY && MaxY <= iVal)
						return MaxY;
					else
						return iVal;
				}
			}
			set
			{
				if(HasMaxY && MaxY >= value  || value <= 0)
					SetExtendedAttribute( "PictureDetailsY", null );
				else
					SetExtendedAttribute( "PictureDetailsY", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the quality percentage of the image shown on the picture details screen
		/// </summary>
		public int PictureDetailsQuality
		{
			get
			{
				string val = GetExtendedAttribute( "PictureDetailsQuality" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return Quality;
			}
			set
			{
				if(value == Quality)
					SetExtendedAttribute( "PictureDetailsQuality", null );
				else
					SetExtendedAttribute( "PictureDetailsQuality", value.ToString() );
			}
		}

		#endregion

		#region Slideshow

		public GalleryImageSettings GetSlideshowSettings()
		{
			GalleryImageSettings slideshow = new GalleryImageSettings(GalleryImageType.Slideshow, SlideshowX,SlideshowY,SlideshowQuality);

			return slideshow;

		}

		/// <summary>
		/// This property defines the width of slideshow images
		/// </summary>
		public int SlideshowX
		{
			get
			{
				string val = GetExtendedAttribute( "SlideshowX" );
				if(val != string.Empty)
				{
					int iVal = int.Parse(val); 
					if(HasMaxX && MaxX <= iVal)
						return MaxX;
					else
						return iVal;
				}
				else
				{
					int iVal = 640; 
					if(HasMaxX && MaxX <= iVal)
						return MaxX;
					else
						return iVal;
				}
			}
			set
			{
				if(HasMaxX && MaxX >= value  || value <= 0)
					SetExtendedAttribute( "SlideshowX", null );
				else
					SetExtendedAttribute( "SlideshowX", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the height of slideshow images
		/// </summary>
		public int SlideshowY
		{
			get
			{
				string val = GetExtendedAttribute( "SlideshowY" );
				if(val != string.Empty)
				{
					int iVal = int.Parse(val); 
					if(HasMaxY && MaxY <= iVal)
						return MaxY;
					else
						return iVal;
				}
				else
				{
					int iVal = 480; 
					if(HasMaxY && MaxY <= iVal)
						return MaxY;
					else
						return iVal;
				}
			}
			set
			{
				if(HasMaxY && MaxY >= value  || value <= 0)
					SetExtendedAttribute( "SlideshowY", null );
				else
					SetExtendedAttribute( "SlideshowY", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the quality percentage of slideshow images
		/// </summary>
		public int SlideshowQuality
		{
			get
			{
				string val = GetExtendedAttribute( "SlideshowQuality" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return Quality;
			}
			set
			{
				if(value == Quality)
					SetExtendedAttribute( "SlideshowQuality", null );
				else
					SetExtendedAttribute( "SlideshowQuality", value.ToString() );
			}
		}

		#endregion

		#region Original

		public bool HasMaxSize
		{
			get{return (HasMaxX || HasMaxY);}
		}

		public bool HasMaxX
		{
			get{return (MaxX != -1);}
		}
		public bool HasMaxY
		{
			get{return (MaxY != -1);}
		}

		public bool ExceedsMaxSize(int Width, int Height)
		{
			bool retVal = false;

			if(HasMaxX && MaxX > Width)
				retVal = true;

			if(HasMaxY && MaxY > Height)
				retVal = true;

			return retVal;

		}

		public GalleryImageSettings GetMaxSettings()
		{
			GalleryImageSettings max = new GalleryImageSettings(GalleryImageType.Original, MaxX,MaxY,Quality);
			return max;
		}

		/// <summary>
		/// This property defines the maximum width of original images
		/// </summary>
		public int MaxX
		{
			get
			{
				string val = GetExtendedAttribute( "MaxX" );
				if(val != string.Empty && (!config.HasMaxX || int.Parse(val) < config.MaxX)) 
					return int.Parse(val);
				else
					return config.MaxX;
			}
			set
			{
				if(HasMaxX && value >= MaxX || value <= 0)
					SetExtendedAttribute( "MaxX", null);
				else
					SetExtendedAttribute( "MaxX", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the maximum height of original images
		/// </summary>
		public int MaxY
		{
			get
			{
				string val = GetExtendedAttribute( "MaxY" );
				if(val != string.Empty && (!config.HasMaxY || int.Parse(val) < config.MaxY))
					return int.Parse(val);
				else
					return config.MaxY;
			}
			set
			{
				if(HasMaxY && value >= MaxY || value <= 0)
					SetExtendedAttribute( "MaxY", null);
				else
					SetExtendedAttribute( "MaxY", value.ToString() );
			}
		}

		/// <summary>
		/// This property defines the quality percentage of original images if scaled
		/// </summary>
		public int Quality
		{
			get
			{
				string val = GetExtendedAttribute( "Quality" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return config.Quality;
			}
			set
			{
				if(value == config.Quality)
					SetExtendedAttribute( "Quality", null );
				else
					SetExtendedAttribute( "Quality", value.ToString() );
			}
		}

		#endregion

		#region Watermark

		public bool HasWatermark
		{
			get{return (WatermarkType != WatermarkType.None);}
		}

		/// <summary>
		/// The X dimension of the image as a threshold for watermarking
		/// </summary>
		public int WatermarkMinWidth
		{
			get
			{
				string val = GetExtendedAttribute( "WatermarkMinWidth" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return 0;
			}
			set { SetExtendedAttribute( "WatermarkMinWidth", value.ToString() ); }
		}

		/// <summary>
		/// The Y dimension of the image in pixels as a threashold for watermarking
		/// </summary>
		public int WatermarkMinHeight
		{
			get
			{
				string val = GetExtendedAttribute( "WatermarkMinHeight" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return 0;
			}
			set { SetExtendedAttribute( "WatermarkMinHeight", value.ToString() ); }
		}

		public string WatermarkText
		{
			get
			{
				string val = GetExtendedAttribute( "WatermarkText" );
				if(val != string.Empty)
					return val;
				else
					return "";
			}
			set { SetExtendedAttribute( "WatermarkText", value.ToString() ); }
		}
	
		public WatermarkType WatermarkType
		{
			get
			{
				string val = GetExtendedAttribute( "WatermarkType" );
				if(val != string.Empty)
					return (WatermarkType)Enum.Parse(typeof(WatermarkType),val);
				else
					return WatermarkType.None;
			}
			set { SetExtendedAttribute( "WatermarkType", value.ToString() ); }
		}

		public WatermarkPosition WatermarkPosition
		{
			get
			{
				string val = GetExtendedAttribute( "WatermarkPosition" );
				if(val != string.Empty)
					return (WatermarkPosition)Enum.Parse(typeof(WatermarkPosition),val);
				else
					return WatermarkPosition.MIDDLE;
			}
			set { SetExtendedAttribute( "WatermarkPosition", value.ToString() ); }
		}

		#endregion


		#endregion

		#region Themes

        private static GalleryConfiguration config = GalleryConfiguration.Instance();
		private string theme = null;
		public string  Theme
		{
			get
			{
				if(theme == null)
				{
					theme =  GetString("Theme",null);
                    
                    
					if(Globals.IsNullorEmpty(theme) || !config.EnableThemes)
						theme = config.DefaultTheme;
				}
				return theme;
			}

			set
			{

				//If updated value == Default Value, set to null. Otherwise, just update the inernal
				//store and set the local variable
				if(string.Compare(value, config.DefaultTheme) == 0)
					SetExtendedAttribute("Theme", null);
				else
					SetExtendedAttribute("Theme", value);

				theme = value;
			}
		}

        private string secondaryCSS = null;
        public string SecondaryCSS
		{
			get
			{
                if (secondaryCSS == null)
                {
                    secondaryCSS = GetString("SecondaryCSS", null);


                    if (Globals.IsNullorEmpty(secondaryCSS) || !config.EnableThemes)
                        secondaryCSS = config.DefaultSecondaryCSS;
                }
                return secondaryCSS;
			}
			set
			{
                //If updated value == Default Value, set to null. Otherwise, just update the inernal
                //store and set the local variable
                if (string.Compare(value, config.DefaultSecondaryCSS) == 0)
                    SetExtendedAttribute("SecondaryCSS", null);
                else
                    SetExtendedAttribute("SecondaryCSS", value);

                secondaryCSS = value;
			}
		}

		public string CSSOverride
		{
			get { return GetString("CSSOverride", null); }
			set { SetExtendedAttribute("CSSOverride", value); }
		}

		#endregion

		#region Counts
		private int _postCount;
		/// <summary>
		/// Property PostCount (int)
		/// </summary>
		public int PostCount
		{
			get {  return this._postCount; }
			set {  this._postCount = value; }
		}

		private int _commentCount;
		/// <summary>
		/// Property CommentCount (int)
		/// </summary>
		public int CommentCount
		{
			get {  return this._commentCount; }
			set {  this._commentCount = value; }
		}

		private int _trackbackCount;
		/// <summary>
		/// Property TrackbackCount (int)
		/// </summary>
		public int TrackbackCount
		{
			get {  return this._trackbackCount; }
			set {  this._trackbackCount = value; }
		}
		#endregion

        public override string Url
        {
            get{ return GalleryUrls.Instance().ViewGallery(this.ApplicationKey);}
        }

		private int GetLowerQuota(int current, int compare)
		{
			const int unset = -1;
			int lower = current;

			if(compare > unset)
			{
				if((compare < current && current > unset) || current == unset)
					lower = compare;
			}

			return lower;
		}

		public int GetActiveQuota(GalleryQuotaType quotaType)
		{
			int activeQuota = -1;

			switch(quotaType)
			{
				case GalleryQuotaType.Disk:
					activeQuota = GetLowerQuota(activeQuota, this.DiskQuota);
					activeQuota = GetLowerQuota(activeQuota, GalleryRoleQuotas.GetMaxRoleQuota(this, GalleryQuotaType.Disk));
					activeQuota = GetLowerQuota(activeQuota, config.DiskQuota);
					break;
				case GalleryQuotaType.Image:
					activeQuota = GetLowerQuota(activeQuota, this.ImageQuota);
					activeQuota = GetLowerQuota(activeQuota, GalleryRoleQuotas.GetMaxRoleQuota(this, GalleryQuotaType.Image));
					activeQuota = GetLowerQuota(activeQuota, config.ImageQuota);
					break;
				default:
					throw new ArgumentException("This quota type is not supported.");
			}

			return activeQuota;
		}

		public bool ValidateRatings(GalleryPost post)
		{
			if(!EnableRatingsOverride)
				return false;

			return post.EnableRatings;
		}

		public bool ValidateTrackBacks(GalleryPost post)
		{
			if(!EnableTrackbacksOverride)
				return false;

			return post.EnableTrackBacks;
		}

		public bool EnableNewComments(GalleryPost post)
		{
			if(!EnableCommentsOverride)
				return false;

			if(!EnableCommentsDefault)
				return false;

			if(!EnableComments)
				return false;

			if(post.IsLocked)
				return false;

			return post.UserTime.AddDays(this.CommentExpirationDays) > DateTime.Now;
			
		}
		public bool EnableNewComments(GalleryPost post, User user)
		{
			if(!Permissions.ValidatePermissions(this,Permission.Reply,user))
				return false;

			return EnableNewComments(post);
		}

		public bool IsPostModerated(GalleryPost post, User user)
		{
			// If the user is one of the gallery owners, their comments are always approved
			if (post.Gallery.IsOwner(user) || user.IsGalleryAdministrator)
				return false;

			if (this.ModerationTypeOverride == CommentModerationType.Ignore)
			{
				switch(post.ModerationType)
				{
					case CommentModerationType.All:
						return true;
					case CommentModerationType.Anonymous:
						return user.IsAnonymous;
					case CommentModerationType.None:
						return false;
					default:
						return true;
				}
			}
			else
			{
				switch(ModerationTypeOverride)
				{
					case CommentModerationType.All:
						return true;
					case CommentModerationType.Anonymous:
						return user.IsAnonymous;
					case CommentModerationType.None:
						return false;
					default:
						return true;
				}
			}
		}

		/// <summary>
		/// The type of feedback the owner should receive notification for.
		/// </summary>
		public FeedbackNotificationType FeedbackNotificationType
		{
			get{ return (FeedbackNotificationType)GetInt("feedbackNotificationType", (int)FeedbackNotificationType.None); }
			set{ this.SetExtendedAttribute("feedbackNotificationType",((int)value).ToString()); }
		}

		public string ReferralFilter
		{
			get{ return Url.ToLower().Replace("/default.aspx",string.Empty).Replace("/viewpicture.aspx",string.Empty).Replace("/viewgallery.aspx",string.Empty).Replace("/viewcatagory.aspx",string.Empty).Replace("/viewexif.aspx",string.Empty).Replace("/slideshow.aspx",string.Empty);}
		}


	}
}
