using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;


namespace FcMirrorVCS
{
	//*****************************************************************************
	//   t@C F frmMirror.cs
	//
	//   @\ F ~[Xe[^X\@\
	//
	//
	// Copyright (C) NEC Corporation 2009
	//*****************************************************************************

	public class frmMirror : System.Windows.Forms.Form
	{
		public System.Windows.Forms.Label lblAllow;
		public System.Windows.Forms.Label lblSmartState;
		public System.Windows.Forms.Label lblDrive2;
		public System.Windows.Forms.Label lblDrive1;
		public System.Windows.Forms.Label LedDrive2;
		public System.Windows.Forms.Label LedDrive1;
		private System.Windows.Forms.Timer timer1;
		private System.ComponentModel.IContainer components;

		//*****************************************************************************
		// HDD擾p萔`
		//*****************************************************************************

		// RETURNXe[^X
		private const int FCSRASAPI_SUCCESS = 0x00;
		private const int FCSRASAPI_DRVERR = 0x01;

	    // HDD̃ANZXw
		private const byte HDDSTS_PRI_MAS = 0x10;			// vC}}X^w
		private const byte HDDSTS_PRI_SRV = 0x20;			// vC}X[uw
		private const byte HDDSTS_SEC_MAS = 0x30;			// ZJ_}X^w
		private const byte HDDSTS_SEC_SRV = 0x40;			// ZJ_X[uw

		private const byte HDDSTS_MRR_DRV1 = 0x01;			// ~[hCuPw
		private const byte HDDSTS_MRR_DRV2 = 0x02;			// ~[hCuQw

		// HDD󋵂ޯď (IOCTL_FCSOFTRAS_GET_HDDINF)
		private const byte HDDCONN_SMARTERR_BIT = 0x01;		// SMARTG[  0:   1:ُ
		private const byte HDDCONN_CONNECT_BIT = 0x40;		// HDDڑ      0:ڑ 1:ڑL
		private const byte HDDCONN_MIRROR_BIT = 0x80;		// װ      0:ڑ 1:ڑL

		// HDDð (IOCTL_FCSOFTRAS_GET_HDDINF)
		private const byte HDDSTS_NORMAL = 0x00;			// 
		private const byte HDDSTS_ERR_DRV1 = 0x10;			// Drive1̏ (ײإϽ or װ_1)
		private const byte HDDSTS_ERR_DRV2 = 0x11;			// Drive2̏ (ײإڰ or װ_2)
		private const byte HDDSTS_ERR_DRV3 = 0x12;			// Drive3̏ (إϽ)
		private const byte HDDSTS_ERR_DRV4 = 0x13;			// Drive4̏ (إڰ)

		private const byte HDDSTS_RECON_1 = 0x20;			// ްč\z(Drive2Drive1ֺ߰)
		private const byte HDDSTS_RECON_2 = 0x21;			// ްč\z(Drive1Drive2ֺ߰)
		private const byte HDDSTS_RECON_SKIP_1 = 0x30;		// غݔ(Drive1Drive2ްč\z)
		private const byte HDDSTS_RECON_SKIP_2 = 0x31;		// غݔ(Drive2Drive1ްč\z)

        private const byte HDDSTS_PATROLRD = 0x50;          // ۰ذޒ

		//*****************************************************************************
		// \tgRASI/F`
		//*****************************************************************************
		[DllImport("FcsrasapiP.dll")]
		private static extern int fcsoftrasOpenP();
		[DllImport("FcsrasapiP.dll")]
		private static extern int fcsoftrasCloseP();
		[DllImport("FcsrasapiP.dll")]
		private static extern int fcsoftrasGetMirrorStatusP(byte DriveNum, [MarshalAs(UnmanagedType.SafeArray)] ref byte[] buff);
		[DllImport("FcsrasapiP.dll")]
		private static extern int fcsoftrasGetMirrorReconProgressP(byte DriveNum, ref byte buff);

		public frmMirror()
		{
			//
			// Windows tH[ fUCi T|[gɕKvłB
			//
			InitializeComponent();

			//
			// TODO: InitializeComponent ĂяǒɁARXgN^ R[hǉĂB
			//
		}

		/// <summary>
		/// gpĂ郊\[XɌ㏈s܂B
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows tH[ fUCiŐꂽR[h 
		/// <summary>
		/// fUCi T|[gɕKvȃ\bhłB̃\bh̓e
		/// R[h GfB^ŕύXȂłB
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(frmMirror));
			this.lblAllow = new System.Windows.Forms.Label();
			this.lblSmartState = new System.Windows.Forms.Label();
			this.lblDrive2 = new System.Windows.Forms.Label();
			this.lblDrive1 = new System.Windows.Forms.Label();
			this.LedDrive2 = new System.Windows.Forms.Label();
			this.LedDrive1 = new System.Windows.Forms.Label();
			this.timer1 = new System.Windows.Forms.Timer(this.components);
			this.SuspendLayout();
			// 
			// lblAllow
			// 
			this.lblAllow.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)));
			this.lblAllow.BackColor = System.Drawing.SystemColors.Control;
			this.lblAllow.Cursor = System.Windows.Forms.Cursors.Default;
			this.lblAllow.Font = new System.Drawing.Font("lr oSVbN", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(128)));
			this.lblAllow.ForeColor = System.Drawing.SystemColors.ControlText;
			this.lblAllow.Location = new System.Drawing.Point(98, 40);
			this.lblAllow.Name = "lblAllow";
			this.lblAllow.RightToLeft = System.Windows.Forms.RightToLeft.No;
			this.lblAllow.Size = new System.Drawing.Size(45, 19);
			this.lblAllow.TabIndex = 9;
			this.lblAllow.Text = "Label1";
			this.lblAllow.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// lblSmartState
			// 
			this.lblSmartState.BackColor = System.Drawing.SystemColors.Control;
			this.lblSmartState.Cursor = System.Windows.Forms.Cursors.Default;
			this.lblSmartState.ForeColor = System.Drawing.SystemColors.ControlText;
			this.lblSmartState.Location = new System.Drawing.Point(0, 72);
			this.lblSmartState.Name = "lblSmartState";
			this.lblSmartState.RightToLeft = System.Windows.Forms.RightToLeft.No;
			this.lblSmartState.Size = new System.Drawing.Size(240, 15);
			this.lblSmartState.TabIndex = 6;
			this.lblSmartState.Text = "Label1";
			this.lblSmartState.TextAlign = System.Drawing.ContentAlignment.TopCenter;
			// 
			// lblDrive2
			// 
			this.lblDrive2.BackColor = System.Drawing.SystemColors.Control;
			this.lblDrive2.Cursor = System.Windows.Forms.Cursors.Default;
			this.lblDrive2.ForeColor = System.Drawing.SystemColors.ControlText;
			this.lblDrive2.Location = new System.Drawing.Point(144, 8);
			this.lblDrive2.Name = "lblDrive2";
			this.lblDrive2.RightToLeft = System.Windows.Forms.RightToLeft.No;
			this.lblDrive2.Size = new System.Drawing.Size(73, 17);
			this.lblDrive2.TabIndex = 8;
			this.lblDrive2.Text = "DRIVE2";
			this.lblDrive2.TextAlign = System.Drawing.ContentAlignment.TopCenter;
			// 
			// lblDrive1
			// 
			this.lblDrive1.BackColor = System.Drawing.SystemColors.Control;
			this.lblDrive1.Cursor = System.Windows.Forms.Cursors.Default;
			this.lblDrive1.ForeColor = System.Drawing.SystemColors.ControlText;
			this.lblDrive1.Location = new System.Drawing.Point(24, 8);
			this.lblDrive1.Name = "lblDrive1";
			this.lblDrive1.RightToLeft = System.Windows.Forms.RightToLeft.No;
			this.lblDrive1.Size = new System.Drawing.Size(73, 17);
			this.lblDrive1.TabIndex = 7;
			this.lblDrive1.Text = "DRIVE1";
			this.lblDrive1.TextAlign = System.Drawing.ContentAlignment.TopCenter;
			// 
			// LedDrive2
			// 
			this.LedDrive2.BackColor = System.Drawing.Color.Green;
			this.LedDrive2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
			this.LedDrive2.Location = new System.Drawing.Point(144, 32);
			this.LedDrive2.Name = "LedDrive2";
			this.LedDrive2.Size = new System.Drawing.Size(73, 33);
			this.LedDrive2.TabIndex = 10;
			// 
			// LedDrive1
			// 
			this.LedDrive1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)(128)), ((System.Byte)(0)));
			this.LedDrive1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
			this.LedDrive1.Location = new System.Drawing.Point(24, 32);
			this.LedDrive1.Name = "LedDrive1";
			this.LedDrive1.Size = new System.Drawing.Size(73, 33);
			this.LedDrive1.TabIndex = 11;
			// 
			// timer1
			// 
			this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
			// 
			// frmMirror
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
			this.ClientSize = new System.Drawing.Size(244, 88);
			this.Controls.Add(this.lblAllow);
			this.Controls.Add(this.lblSmartState);
			this.Controls.Add(this.lblDrive2);
			this.Controls.Add(this.lblDrive1);
			this.Controls.Add(this.LedDrive2);
			this.Controls.Add(this.LedDrive1);
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Location = new System.Drawing.Point(3, 22);
			this.MaximizeBox = false;
			this.MinimizeBox = false;
			this.Name = "frmMirror";
			this.Text = "Mirror State";
			this.Load += new System.EventHandler(this.frmMirror_Load);
			this.Closed += new System.EventHandler(this.frmMirror_Closed);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// AvP[ṼC Gg |CgłB
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new frmMirror());
		}

		//****************************************************
		//   ֐ F frmMirror_Load
		//   @\   Fʂ̋N()
		//      F Ȃ
		//   ߂l F Ȃ
		//****************************************************
		private void frmMirror_Load(object sender, System.EventArgs e)
		{
			int ret;

			// ƃtH_st@CtH_ɕύX DLLǂݏo
			System.IO.Directory.SetCurrentDirectory(Application.StartupPath);

			// \tgRAS̃Cu
			ret = fcsoftrasOpenP();

			// ݂̏Ԃ擾Ɖʂւ̔f
			subSetMirrorState();
		
			// ʍXVp̃^C}[ݒ
			timer1.Interval = 30000;		// 30bݒ
			timer1.Enabled = true;			// L
		
		}

		//****************************************************
		//   ֐ F frmMirror_Closed
		//   @\   Fʂ̏I(㏈)
		//      F Ȃ
		//   ߂l F Ȃ
		//****************************************************
		private void frmMirror_Closed(object sender, System.EventArgs e)
		{
			int ret;

			// \tgRAS̃CuI
			ret = fcsoftrasCloseP();
		}

		//****************************************************
		//   ֐ F timer1_Tick
		//   @\   F^C}[ɂʍXV
		//      F Ȃ
		//   ߂l F Ȃ
		//****************************************************
		private void timer1_Tick(object sender, System.EventArgs e)
		{
			// ݂̏Ԃ擾Ɖʂւ̔f
			subSetMirrorState();
		}

		//****************************************************
		//   ֐ F subSetMirrorState
		//   @\   F~[̏Ԃ擾Aʂ̍XVsȂ
		//      F Ȃ
		//   ߂l F Ȃ
		//****************************************************
		private void subSetMirrorState()
		{
			byte[] buff = new byte[3];	// ~[Xe[^Xۑp
			byte Progress = 0;			// i󋵕ۑp
			int ret;					// ߂lۑp

			// ~[Xe[^X̎擾
			ret = fcsoftrasGetMirrorStatusP(HDDSTS_PRI_MAS, ref buff);
			// ~[Xe[^X擾H
			if (FCSRASAPI_SUCCESS == ret)
			{
				// ~[Xe[^X̏󋵂ɂʂXV
				switch (buff[0])
				{
						// 
					case HDDSTS_NORMAL:
						lblSmartState.Text = "Normal";			// ڍ׏ݒ
						LedDrive1.BackColor = Color.Lime;		// hCu1 LEDݒ()
						LedDrive2.BackColor = Color.Lime;		// hCu2 LEDݒ()
						lblAllow.Text = "";						// č\zp\
						break;

						// hCuPG[
					case HDDSTS_ERR_DRV1:
						lblSmartState.Text = "DRIVE1 failure";	// ڍ׏ݒ
						LedDrive1.BackColor = Color.Red;		// hCu1 LEDݒ()
						LedDrive2.BackColor = Color.Lime;		// hCu2 LEDݒ()
						lblAllow.Text = "";						// č\zp\
						break;

						// hCuQG[
					case HDDSTS_ERR_DRV2:
						lblSmartState.Text = "DRIVE2 failure";	// ڍ׏ݒ
						LedDrive1.BackColor = Color.Lime;		// hCu1 LEDݒ()
						LedDrive2.BackColor = Color.Red;		// hCu2 LEDݒ()
						lblAllow.Text = "";						// č\zp\
						break;

						// f[^č\z(DRIVE1DRIVE2)
					case HDDSTS_RECON_1:
						// i̎擾
						if (FCSRASAPI_SUCCESS == fcsoftrasGetMirrorReconProgressP(HDDSTS_PRI_MAS, ref Progress))
						{
							// ڍ׏ݒ(i܂)
							lblSmartState.Text = "Currently copying(DRIVE1<-DRIVE2)" + Progress + "%";
						}
							// i̎擾s
						else
						{
							// ڍ׏ݒ
							lblSmartState.Text = "Currently copying(DRIVE1<-DRIVE2)";
						}
						LedDrive1.BackColor = Color.Orange;		// hCu1 LEDݒ()
						LedDrive2.BackColor = Color.Lime;		// hCu2 LEDݒ()
						lblAllow.Text = "<<";
						break;

						// f[^č\z(DRIVE1DRIVE2)
					case HDDSTS_RECON_2:
						// i̎擾
						if (FCSRASAPI_SUCCESS == fcsoftrasGetMirrorReconProgressP(HDDSTS_PRI_MAS, ref Progress))
						{
							// ڍ׏ݒ(i܂)
							lblSmartState.Text = "Currently copying(DRIVE1->DRIVE2)" + Progress + "%";
						}
							// i̎擾s
						else
						{
							// ڍ׏ݒ
							lblSmartState.Text = "Currently copying(DRIVE1->DRIVE2)";
						}
						LedDrive1.BackColor = Color.Lime;		// hCu1 LEDݒ()
						LedDrive2.BackColor = Color.Orange;		// hCu2 LEDݒ()
						lblAllow.Text = ">>";					// č\zp\
						break;

						// XLbvR
					case HDDSTS_RECON_SKIP_1:
						lblSmartState.Text = "Skip recon(DRIVE1)";
						LedDrive1.BackColor = Color.Lime;		// hCu1 LEDݒ()
						LedDrive2.BackColor = Color.Lime;		// hCu2 LEDݒ()
						lblAllow.Text = "";						// č\zp\
						break;

						// XLbvR
					case HDDSTS_RECON_SKIP_2:
						// ڍ׏ݒ
						lblSmartState.Text = "Skip recon(DRIVE2)";
						LedDrive1.BackColor = Color.Lime;		// hCu1 LEDݒ()
						LedDrive2.BackColor = Color.Lime;		// hCu2 LEDݒ()
						lblAllow.Text = "";						// č\zp\
						break;

                        // pg[[h
                    case HDDSTS_PATROLRD:
                        // i̎擾
                        if (FCSRASAPI_SUCCESS == fcsoftrasGetMirrorReconProgressP(HDDSTS_PRI_MAS, ref Progress))
                        {
                            // ڍ׏ݒ(i܂)
                            lblSmartState.Text = "Patrol reading " + Progress + "%";
                        }
                            // i̎擾s
                        else
                        {
                            // ڍ׏ݒ
                            lblSmartState.Text = "Patrol reading";
                        }
                        LedDrive1.BackColor = Color.Lime;		// hCu1 LEDݒ()
                        LedDrive2.BackColor = Color.Lime;		// hCu2 LEDݒ()
                        lblAllow.Text = "";						// č\zp\
                        break;

                   }
			}
			else
			{
				// ~[Xe[^X̎擾ŝŖ̏󋵂\
				lblSmartState.Text = "None mirror board";
				lblAllow.Text = "";
				LedDrive1.BackColor = Color.White;
				LedDrive2.BackColor = Color.White;
			}
		}
	}
}
