//                           UNCLASSIFIED
/*-------------------------------------------------------------------------
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
COMPANY.

THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
GOVERNMENT.

UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/

using ExcelZipLib;
using System;
using System.Collections.Generic;
using System.Globalization;

namespace BitMeasurementManagerLib
{
   /// <summary>
   /// This class creates BitConfigurableMessage objects
   /// </summary>
   internal class BitConfigurableMessageExcelZipFactory : BitConfigurableMessageFactory
   {
      #region PrivateClassMembers
      private Dictionary<uint, BitConfigurableMessage> _messageDictionary;
      #endregion

      #region PrivateFuctions

      /// <summary>
      /// 
      /// </summary>
      /// <param name="filename"></param>
      /// <param name="msgIds"></param>
      public BitConfigurableMessageExcelZipFactory(string filename)
      {
         const int MIN_ROWS = 3;
         const int MIN_COLS = 4;

         try
         {
            _messageDictionary = new Dictionary<uint, BitConfigurableMessage>();

            List<worksheet> allWorkSheets = Workbook.Worksheets(filename);

            foreach (worksheet sheet in allWorkSheets)
            {
               string test = sheet.ToString();

               // check that there is the min number of rows
               if (sheet.Rows.Count < MIN_ROWS)
               {
                  throw new Exception("BitConfigurableMessageExcelZipFactory::BitConfigurableMessageExcelZipFactory() - Sheet ID: " + sheet + " does not have the min amount of rows: " + MIN_ROWS.ToString());
               }

               // grab the command ID Row
               Row cmdIdRow = sheet.Rows[1];

               if (cmdIdRow.Cells.Length < MIN_COLS)
               {
                  throw new Exception("BitConfigurableMessageExcelZipFactory::BitConfigurableMessageExcelZipFactory() - Sheet ID: " + sheet + " line 1 does not have the min amount of Cols: " + MIN_COLS.ToString());
               }

               string msgIdStr = cmdIdRow.Cells[3].Text.Trim().ToUpper();

               uint msgId = Convert.ToUInt32(msgIdStr, 16);

               // grab the rsp ID Row
               Row rspIdRow = sheet.Rows[2];

               if (rspIdRow.Cells.Length < MIN_COLS)
               {
                  throw new Exception("BitConfigurableMessageExcelZipFactory::BitConfigurableMessageExcelZipFactory() - Sheet ID: " + sheet + " line 1 does not have the min amount of Cols: " + MIN_COLS.ToString());
               }

               string rspMsgIdStr = rspIdRow.Cells[3].Text.Trim().ToUpper();

               // grab the rsp msg ID
               uint rspMsgId = Convert.ToUInt32(rspMsgIdStr, 16);

               // create the message
               BitConfigurableMessage msg = new BitConfigurableMessage(msgId, rspMsgId, msgId.ToString("X8"));

               //remove header, cmd ID and rsp ID rows from worksheet
               sheet.Rows.Remove(sheet.Rows[0]);
               sheet.Rows.Remove(sheet.Rows[0]);
               sheet.Rows.Remove(sheet.Rows[0]);

               // process the sheet to create the message object
               // start at 1 to skip the file header
               foreach (Row row in sheet.Rows)
               {
                  if (row.Cells.Length < MIN_COLS)
                  {
                     throw new Exception("BitConfigurableMessageExcelZipFactory::BitConfigurableMessageFactory() - Sheet ID: " + msgId.ToString("X8") + " does not have all of the fields populated");
                  }

                  string dataItemName = row.Cells[0].Text.Trim().ToUpper();

                  string fieldType = row.Cells[1].Text.Trim().ToUpper();
                  string numberOfItemsTemp = row.Cells[2].Text.Trim().ToUpper();
                  numberOfItemsTemp = numberOfItemsTemp.Replace(",", "");
                  int numberOfItems = Convert.ToInt32(numberOfItemsTemp);
                  string defaultValue = row.Cells[3].Text.Trim().ToUpper();

                  BitConfigurableMessage.DataItemType dataType = BitConfigurableMessage.DataItemType.FLOAT;

                  if (fieldType == BitInterfaceManagerConstants.FLOAT_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.FLOAT;
                  }
                  else if (fieldType == BitInterfaceManagerConstants.UINT_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.UINT;
                  }
                  else if (fieldType == BitInterfaceManagerConstants.UINT_HEX_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.UINT_HEX;
                  }
                  else if (fieldType == BitInterfaceManagerConstants.USHORT_HEX_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.USHORT_HEX;
                  }
                  else if (fieldType == BitInterfaceManagerConstants.USHORT_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.USHORT;
                  }
                  else if (fieldType == BitInterfaceManagerConstants.BYTE_HEX_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.BYTE_HEX;
                  }
                  else if (fieldType == BitInterfaceManagerConstants.BYTE_ARRAY_HEX_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.BYTE_ARRAY_HEX;
                  }
                  else if (fieldType == BitInterfaceManagerConstants.DOUBLE_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.DOUBLE;
                  }
                  else if (fieldType == BitInterfaceManagerConstants.ULONG_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.ULONG;
                  }
                  else if (fieldType == BitInterfaceManagerConstants.ULONG_HEX_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.ULONG_HEX;
                  }
                  else if (fieldType == BitInterfaceManagerConstants.BITS_DATA_TYPE.ToUpper())
                  {
                     dataType = BitConfigurableMessage.DataItemType.BITS;
                  }
                  else
                  {
                     throw new Exception("BitConfigurableMessageExcelZipFactory::BitConfigurableMessageExcelZipFactory() - Unknown type: " + row.FilledCells[0].ToString());
                  }

                  msg.AddDataItem(dataItemName, dataType, numberOfItems, defaultValue);
               }

               // hold onto the message object
               _messageDictionary[msgId] = msg;
            }
         }
         catch (Exception)
         {
            throw;
         }
      }
      #endregion

      #region PublicFuctions

      /// <summary>
      /// 
      /// </summary>
      /// <param name="messageId"></param>
      /// <returns></returns>
      protected override BitConfigurableMessage CreateMessage(uint messageId)
      {
         if (_messageDictionary.ContainsKey(messageId) == false)
         {
            throw new Exception("BitConfigurableMessageExcelZipFactory:CreateMessage() - unknown ID: " + messageId.ToString("X8") + ", make sure this ID is defined in the definition ini file");
         }

         return new BitConfigurableMessage(_messageDictionary[messageId]);
      }

      /// <summary>
      /// 
      /// </summary>
      /// <returns></returns>
      protected override Dictionary<uint, BitConfigurableMessage> GetAllMessages()
      {
         return _messageDictionary;
      }
      #endregion
   }
}