//------------------------------------------------------------------------------
//
// Copyright (c) 2002-2006 CodeSmith Tools, LLC.  All rights reserved.
// 
// The terms of use for this software are contained in the file
// named sourcelicense.txt, which can be found in the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by the
// terms of this license.
// 
// You must not remove this notice, or any other, from this software.
//
//------------------------------------------------------------------------------

using System;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Drawing.Design;
using System.ComponentModel;
using System.Security.Permissions;
using CodeSmith.Engine;

namespace CodeSmith.CustomProperties
{
	[SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)]
	public class FileNameEditor : UITypeEditor
	{
		private FileDialog fileDialog;
		
		public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
		{
			return UITypeEditorEditStyle.Modal;
		}
		
		protected virtual void InitializeDialog(FileDialog fileDialog, ITypeDescriptorContext context)
		{
			fileDialog.Filter = "All Files (*.*)|*.*";
			fileDialog.Title = "Select " + context.PropertyDescriptor.DisplayName;
		}
		
		public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
		{
			if (provider != null)
			{
				IWindowsFormsEditorService service = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
				if (service == null) return value;
				
				FileDialogAttribute fileDialogAttribute = (FileDialogAttribute)context.PropertyDescriptor.Attributes[typeof(FileDialogAttribute)];
				if (fileDialogAttribute != null)
				{
					if (fileDialogAttribute.DialogType == FileDialogType.Open)
					{
						fileDialog = new OpenFileDialog();
					}
					else
					{
						fileDialog = new SaveFileDialog();
					}
					this.InitializeDialog(fileDialog, context);
					
					if (fileDialogAttribute.IsFilterSet) fileDialog.Filter = fileDialogAttribute.Filter;
					if (fileDialogAttribute.IsTitleSet) fileDialog.Title = fileDialogAttribute.Title;
					if (fileDialogAttribute.IsDefaultExtensionSet) fileDialog.DefaultExt = fileDialogAttribute.DefaultExtension;
					if (fileDialogAttribute.IsCheckFileExistsSet) fileDialog.CheckFileExists = fileDialogAttribute.CheckFileExists;
					if (fileDialogAttribute.IsCheckPathExistsSet) fileDialog.CheckPathExists = fileDialogAttribute.CheckPathExists;
				}
				else
				{
					fileDialog = new SaveFileDialog();
					this.InitializeDialog(fileDialog, context);
				}
				
				string defaultFileName = String.Empty;
				
				if (context.Instance is CodeTemplate)
				{
					defaultFileName = ((CodeTemplate)context.Instance).GetFileName();
				}
				
				if (value is string && ((string)value).Length > 0)
				{
					defaultFileName = (string)value;
				}
				
				fileDialog.FileName = defaultFileName;
				if (fileDialog.ShowDialog() == DialogResult.OK)
				{
					value = fileDialog.FileName;
				}
			}
			
			return value;
		}
 	}
	
	public enum FileDialogType
	{
		Save,
		Open
	}
	
	[AttributeUsage(AttributeTargets.Property)]
	public class FileDialogAttribute : Attribute
	{
		private FileDialogType _dialogType = FileDialogType.Save;
		
		private string _filter = "All Files (*.*)|*.*";
		private bool _isFilterSet = false;
		
		private string _title = String.Empty;
		private bool _isTitleSet = false;
		
		private string _defaultExtension = String.Empty;
		private bool _isDefaultExtensionSet = false;
		
		private bool _checkFileExists = false;
		private bool _isCheckFileExistsSet = false;
		
		private bool _checkPathExists = false;
		private bool _isCheckPathExistsSet = false;
		
		public FileDialogAttribute(FileDialogType dialogType)
		{
			_dialogType = dialogType;
		}
		
		public FileDialogType DialogType
		{
			get {return _dialogType;}
			set {_dialogType = value;}
		}
		
		public string Filter
		{
			get {return _filter;}
			set
			{
				_filter = value;
				_isFilterSet = true;
			}
		}
		
		public bool IsFilterSet
		{
			get {return _isFilterSet;}
		}
		
		public string Title
		{
			get {return _title;}
			set
			{
				_title = value;
				_isTitleSet = true;
			}
		}
		
		public bool IsTitleSet
		{
			get {return _isTitleSet;}
		}
		
		public string DefaultExtension
		{
			get {return _defaultExtension;}
			set
			{
				_defaultExtension = value;
				_isDefaultExtensionSet = true;
			}
		}
		
		public bool IsDefaultExtensionSet
		{
			get {return _isDefaultExtensionSet;}
		}
		
		public bool CheckFileExists
		{
			get {return _checkFileExists;}
			set
			{
				_checkFileExists = value;
				_isCheckFileExistsSet = true;
			}
		}
		
		public bool IsCheckFileExistsSet
		{
			get {return _isCheckFileExistsSet;}
		}
		
		public bool CheckPathExists
		{
			get {return _checkPathExists;}
			set
			{
				_checkPathExists = value;
				_isCheckPathExistsSet = true;
			}
		}
		
		public bool IsCheckPathExistsSet
		{
			get {return _isCheckPathExistsSet;}
		}
	}
}