using System;
using System.Windows.Forms;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Diagnostics;
using System.Collections;
using nft.framework;
using nft.framework.drawing;
using nft.win32util;
using System.Text;

namespace nft.util
{
    public delegate void AdditonalSystemInfoHandler(ConfigureService.SystemInfoText infoText);

    /// <summary>
	/// ConfigureService の概要の説明です。
	/// </summary>
	public class ConfigureService
	{
		private ConfigureService()
		{
		}

		static public string GetSystemInfo()
		{
		    BuildSysInfoText();
            return infoText.FullText;
		}

		static private ArrayList list = new ArrayList();
		static public void RegisterAssembly( Assembly asm )
		{
			list.Add(asm);
			//BuildSysInfoText();
		}

		#region build system information text
        static public event AdditonalSystemInfoHandler OnSystemInfoRequested;

        static private SystemInfoText infoText = new SystemInfoText();
		static private void BuildSysInfoText()
		{
            infoText.Reset();
            infoText.Append("Assembly", Assembly.GetExecutingAssembly().FullName);
			foreach( Assembly asm in list )
                infoText.Append("Assembly", asm.FullName);
            infoText.Append("CLR Version", RuntimeEnvironment.GetSystemVersion());
			Assembly mscore = Assembly.GetAssembly(typeof(string));
            FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(mscore.Location);
            infoText.AppendInline(mscore.GetName().Name + " win32 version", fvi.FileVersion);
            //infoText.AppendInline(mscore.GetName().Name + " win32 version", Win32Version.GetAssemblyFileVersion(mscore));
//			using( Form f = new Form())
//			{
//				Assembly forms = Assembly.GetAssembly(f.GetType());
//				append(forms.GetName().Name,Win32Version.GetAssemblyFileVersion(forms));
//			}
            infoText.Append("Operating System", Environment.OSVersion.ToString());
			GlobalMemoryInfo info = new GlobalMemoryInfo();
            string proctxt = string.Format("{0} (Cores={1})", Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER")
                ,Environment.ProcessorCount);
            infoText.Append("Processor", proctxt);
			string memtext = string.Format("Physical {0:#,##0,,}MB/{1:#,##0,,}MB,  Virtual {2:#,##0,,}MB/{3:#,##0,,}MB",
					info.PhysicalMemAvailable,info.PhysicalMemTotal,
					info.VirtualMemAvailable,info.VirtualMemTotal);
            infoText.Append("System Memory", memtext);
            infoText.Append("Process Context Memory", string.Format("{0:#,##,,}MB", Environment.WorkingSet));
            if (OnSystemInfoRequested != null) {
                Delegate[] delegates = OnSystemInfoRequested.GetInvocationList();
                foreach (Delegate d in delegates) {
                    try {
                        d.DynamicInvoke(infoText);
                    } catch(Exception e) {
                        Debug.WriteLine(e.Message);
                        Debug.WriteLine(e.StackTrace);
                    }
                }
            }
            /*
			try
			{
				IGraphicManagerOld gm = GlobalModules.GraphicManagerOld;
				if(gm!=null){
					append("Video Memory",string.Format("{0:#,##0,,}MB/{1:#,##0,,}MB",
						gm.AvailableVideoMemory,gm.TotalVideoMemory));
					Size scsize = Screen.PrimaryScreen.Bounds.Size;
					string modetext = string.Format("color {0} {1}x{2}",gm.CurrentColorMode,scsize.Width,scsize.Height);
					append("Display Mode",modetext);
				}
			}
			catch(Exception e)
			{
				Debug.WriteLine(e.Message);
				Debug.WriteLine(e.StackTrace);
			}
            */
		}
        public class SystemInfoText
        {
            private StringBuilder textBuffer = new StringBuilder();
            internal void Reset() {
                textBuffer.Remove(0, textBuffer.Length);
            }

            public void Append(string name, string val) {
                if (textBuffer != null)
                    textBuffer.Append(Environment.NewLine);
                textBuffer.Append(string.Format("{0} : {1}", name, val));
            }
            public void AppendInline(string name, string val) {
                textBuffer.Append(string.Format(", {0} : {1}", name, val));
            }

            internal string FullText {
                get { return textBuffer.ToString(); }
            }
        }
		#endregion
	}
}
