//                           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 Raytheon.Common;
using System;
using System.Collections.Generic;

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

      #region PrivateFuctions

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

         ExcelReader reader = null;

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

            reader = new ExcelReader(filename);

            List<string> sheetNamesList = reader.ReadAllSheetNames();

            foreach (string sheet in sheetNamesList)
            {
               // read the whole sheet and split on the lines
               string entireSheet = reader.ReadAllRows(sheet, 1, 1);
               string[] allRows = entireSheet.Split('\n');

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

               // grab the first line where the command ID should be
               string messageIdLine = allRows[1];
               string[] messageIdLineTokens = messageIdLine.Split(',');

               // check for the min number of columns
               if (messageIdLineTokens.Length < MIN_COLS)
               {
                  throw new Exception("BitConfigurableMessageExcelFactory::BitConfigurableMessageExcelFactory() - Sheet ID: " + sheet + " line 1 does not have the min amount of Cols: " + MIN_COLS.ToString());
               }

               // grab the message ID
               uint msgId = Convert.ToUInt32(messageIdLineTokens[3], 16);

               // grab the line with the response msg ID
               string rspMessageIdLine = allRows[2];
               string[] rspMessageIdLineTokens = rspMessageIdLine.Split(',');

               // check the number of cols
               if (rspMessageIdLineTokens.Length < MIN_COLS)
               {
                  throw new Exception("BitConfigurableMessageExcelFactory::BitConfigurableMessageExcelFactory() - Sheet ID: " + sheet + " line 2 does not have the min amount of Cols: " + MIN_COLS.ToString());
               }

               // grab the rsp msg ID
               uint rspMsgId = Convert.ToUInt32(rspMessageIdLineTokens[3], 16);

               // create the message
               BitConfigurableMessage msg = new BitConfigurableMessage(msgId, rspMsgId, sheet);

               // process the sheet to create the message object
               // we already processed the first two lines, start at 3
               for (int i = 3; i < allRows.Length; i++)
               {
                  var line = allRows[i];
                  var values = line.Split(',');

                  if (values.Length < MIN_COLS)
                  {
                     throw new Exception("BitConfigurableMessageExcelFactory::BitConfigurableMessageExcelFactory() - Sheet ID: " + msgId.ToString("X8") + " does not have all of the fields populated");
                  }

                  string dataItemName = values[0].Trim().ToUpper();
                  string fieldType = values[1].Trim().ToUpper();
                  string numberOfItemsTemp = values[2].Trim().ToUpper();
                  numberOfItemsTemp = numberOfItemsTemp.Replace(",", "");
                  int numberOfItems = Convert.ToInt32(numberOfItemsTemp);
                  string defaultValue = values[3].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("BitConfigurableMessageExcelFactory::BitConfigurableMessageExcelFactory() - Unknown type: " + values[1]);
                  }

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

               _messageDictionary[msgId] = msg;
            }
         }
         catch (Exception)
         {
            throw;
         }
         finally
         {
            if (reader != null)
            {
               reader.Dispose();
            }
         }
      }

      #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("BitConfigurableMessageExcelFactory: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
   }
}