using namespace System;
using namespace System::Xml;
using namespace System::Windows::Forms;
using namespace System::Drawing;

namespace CLITableur
{
	/// <summary>
	/// Cellule représente une valeur ou une formule formatée
	///	</summary>
	public ref class Cellule
	{        

	private: 
		/// <summary>
		/// Valeur "calculée" d'une cellule (membre privé)
		///	</summary>
		String^ value;

		/// <summary>
		/// Formule (membre privé)
		///	</summary>
		String^ formula;

		/// <summary>
		/// Style gras (membre privé)
		///	</summary>
		bool isBold;

		/// <summary>
		/// Style italique (membre privé)
		///	</summary>
		bool isItalic;

		/// <summary>
		/// Style souligné (membre privé)
		///	</summary>
		bool isUnderlined;

		/// <summary>
		/// Style couleur de fond (membre privé)
		///	</summary>
		Color backgroundColor;

		/// <summary>
		/// Style couleur d'avant plan (membre privé)
		///	</summary>
		Color foreColor;

		/// <summary>
		/// Style police (membre privé)
		///	</summary>
		String^ fontName;

		/// <summary>
		/// Style taille de la police (membre privé)
		///	</summary>
		float fontSize;

		/// <summary>
		/// Style alignement (membre privé)
		///	</summary>
		DataGridViewContentAlignment alignment;
		
	public:
		/// <summary>
		/// Formatages possible de la valeur
		///	</summary>
		enum class FormatType
		{
			AUTOMATIQUE, NOMBRE, POURCENTAGE, DATE, TEXT, PERSONNALISE
		};


	private:
		/// <summary>
		/// Formatage de la valeur (membre privé)
		///	</summary>
		FormatType format;

		/// <summary>
		/// Chaîne de formatage (membre privé)
		///	</summary>
		String^ formatString;

	public:
		/// <summary>
		/// Obtient ou définit la chaîne de formatage de la valeur.
		/// Réinitialisé lorsque la propriété Format est définie.
		///	</summary>
		property String^ FormatString
		{
			String^ get() 
			{ 
				return formatString; 
			}

			void set(String^ value) 
			{ 
				formatString = value; 
			}
		}

		/// <summary>
		/// Obtient ou définit le format
		///	</summary>
		property FormatType Format
		{
			FormatType get() 
			{ 
				return format; 			
			}

			void set(FormatType value) 
			{ 
				format = value; 
				switch(format)
				{
				case FormatType::AUTOMATIQUE:
				default:
					formatString="";
					break;
				case FormatType::NOMBRE:
					formatString = "{0:n2}";
					break;				
				case FormatType::POURCENTAGE:
					formatString = "{0}%";
					break;
				}
			}
		}

		/// <summary>
		/// Obtient ou définit la valeur formatée
		///	</summary>
		property String^ FormattedValue
		{
			String^ get()
			{
				switch(format)
				{
				case FormatType::AUTOMATIQUE:
				default:
					return value;

				case FormatType::NOMBRE:
					return String::Format(formatString,NumberValue);

				case FormatType::POURCENTAGE:
					return String::Format(formatString,NumberValue*100);

				case FormatType::PERSONNALISE:
					return String::Format(formatString,NumberValue);
				}
			}

			void set(String^ value)
			{
				switch(format)
				{
				case FormatType::AUTOMATIQUE:
				default:
					this->value = value;
					break;

				case FormatType::NOMBRE:
					this->value = "" + Double::Parse(value);
					break;

				case FormatType::POURCENTAGE:
					try 
					{
						double d = Double::Parse(value->Substring(0,value->Length-1));
						Value = "" + (d/100);
					}
					catch(...)
					{

					}
					break;
				case FormatType::PERSONNALISE:
					try 
					{
						double d = Double::Parse(value);
						Value = "";
					}
					catch(...)
					{

					}
					break;
				}
			}
		}

		/// <summary>
		/// Obtient ou définit la valeur
		///	</summary>
		property String^ Value
		{
			String^ get() 
			{ 
				return value; 
			}

			void set(String^ value) 
			{ 
				this->value=value; 
			}
		}

		/// <summary>
		/// Obtient ou définit la formule (ou le texte)
		///	</summary>
		property String^ Formula
		{
			String^ get() 
			{ 
				return formula; 
			}

			void set(String^ value) 
			{ 
				this->formula=value; 
			}
		}

		/// <summary>
		/// Obtient ou définit la valeur numérique
		///	</summary>
		property double NumberValue {
			double get() 
			{
				try 
				{
					return Double::Parse(value);
				}
				catch(...)
				{
					return 0;
				}
			}

			void set(double value) 
			{
				this->value= "" + value;
			}
		}
		
		/// <summary>
		/// Indique si la valeur peut être reconnue comme nombre
		///	</summary>
		bool IsNumber();		


		/// <summary>
		/// Constructeur
		///	</summary>
		Cellule();
									
		/// <summary>
		/// Sérialise la cellule au format XML
		///	</summary>
        XmlNode^ ToXml(XmlDocument^ doc, int col, int row);                

		/// <summary>
		/// Désérialise la cellule à partir d'un noeud XML
		///	</summary>
        void FromXml(XmlNode^ n);       
        

		/// <summary>
		/// Obtient ou définit le style gras
		///	</summary>
		property bool IsBold
		{
			bool get() 
			{ 
				return isBold; 
			}

			void set(bool value) 
			{ 
				isBold = value; 
			}
		}

		/// <summary>
		/// Obtient ou définit le style italique
		///	</summary>
		property bool IsItalic
		{
			bool get() 
			{ 
				return isItalic; 
			}
			
			void set(bool value) 
			{ 
				isItalic = value; 
			}
		}

		/// <summary>
		/// Obtient ou définit le style souligné
		///	</summary>
		property bool IsUnderlined
		{
			bool get() 
			{ 
				return isUnderlined; 
			}
			
			void set(bool value) 
			{ 
				isUnderlined = value; 
			}
		}

		/// <summary>
		/// Obtient ou définit le style couleur de fond
		///	</summary>
		property Color BackgroundColor
		{
			Color get() 
			{ 
				return backgroundColor; 
			}

			void set(Color value) 
			{ 
				backgroundColor = value; 
			}
		}
		
		/// <summary>
		/// Obtient ou définit le style couleur d'avant plan
		///	</summary>
		property Color ForeColor
		{
			Color get() 
			{ 
				return foreColor; 
			}

			void set(Color value) 
			{ 
				foreColor = value; 
			}
		}

		/// <summary>
		/// Obtient ou définit l'alignement
		///	</summary>
		property DataGridViewContentAlignment Alignment
		{
			DataGridViewContentAlignment get() 
			{ 
				return alignment; 
			}

			void set(DataGridViewContentAlignment value) 
			{ 
				alignment = value; 
			}
		}

		/// <summary>
		/// Obtient ou définit la police
		///	</summary>
		property String^ FontName
		{
			String^ get() 
			{ 
				return fontName; 
			}

			void set(String^ value) 
			{ 
				fontName = value; 
			}
		}
		
		/// <summary>
		/// Obtient ou définit la taille de police
		///	</summary>
		property float FontSize
		{
			float get() { return fontSize; }
			void set(float value) { fontSize = value; }
		}
	};
}