// **********************************************************************************************************
//    coeDataInterchangePackets.cs
//    6/1/2022
//    NGI - Next Generation Interceptor
//    
//    Contract No. HQ0856-21-C-0003/1022000209
//    
//    THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S. 
//    INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
//    
//    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.
//    
//    UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
//    
//    DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M, 
//    NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006, 
//    INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3, 
//    DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3, 
//    SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4, 
//    INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
//    
//    CONTROLLED BY: MISSILE DEFENSE AGENCY
//    CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
//    CUI CATEGORY: CTI 
//    DISTRIBUTION/DISSEMINATION CONTROL: F 
//    POC: Alex Kravchenko (1118268)
// **********************************************************************************************************

//\\<Unclassified>
//----------------------------------------------------------------------------//
//                                 UNCLASSIFIED                               //
//----------------------------------------------------------------------------//
//\\<\Unclassified>

//\\<UnlimitedRights>
//----------------------------------------------------------------------------//
// Copyright %(copyright)s Raytheon Company.                                  //
// This software was developed pursuant to Contract Number %(contractNumber)s //
// with the U.S. government. The U.S. government's rights in and to this      //
// copyrighted software are as specified in DFARS 252.227-7014 which was made //
// part of the above contract.                                                //
//----------------------------------------------------------------------------//
//\\<\UnlimitedRights>

//\\<EximUndetermined>
//----------------------------------------------------------------------------//
// WARNING - This document contains technical data and / or technology whose  //
// export or disclosure to Non-U.S. Persons, wherever located, is restricted  //
// by the International Traffic in Arms Regulations (ITAR) (22 C.F.R.         //
// Section 120-130) or the Export Administration Regulations (EAR) (15 C.F.R. //
// Section 730-774). This document CANNOT be exported (e.g., provided to a    //
// supplier outside of the United States) or disclosed to a Non-U.S. Person,  //
// wherever located, until a final jurisdiction and classification            //
// determination has been completed and approved by Raytheon, and any         //
// required U.S. Government approvals have been obtained. Violations are      //
// subject to severe criminal penalties.                                      //
//----------------------------------------------------------------------------//
//\\<\EximUndetermined>

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Raytheon.Common.Coe
{
    //
    //
    //
    // Data Interchange Packet
    //
    //
    //
    public class coeDataInterchangePackets
    {
        private Dictionary<uint, IntPtr> _packets;
        public coe.CallBackDelegate _delegate;
        private GCHandle _GCdelegate;

        internal coeDataInterchangePackets()
        {
            _packets = new Dictionary<uint, IntPtr>();
            _delegate = new coe.CallBackDelegate(Find);
            _GCdelegate = GCHandle.Alloc(_delegate);
        }

        ~coeDataInterchangePackets()
        {
            foreach (KeyValuePair<uint, IntPtr> entry in _packets)
            {
                Marshal.FreeHGlobal(entry.Value);
            }
            _GCdelegate.Free();
        }

        internal IntPtr Find(uint Label)
        {
            _packets.TryGetValue(Label, out IntPtr packetArray);
            return packetArray;
        }

        private void FormatString(byte[] dataBuffer, ref uint StartingIndex, string Name)
        {
            uint index;
            for (index = 0; index < Name.Length && index < 39; index++)
            {
                dataBuffer[StartingIndex++] = (byte)Name[(int)index];
            }
            for (; index < 40; index++)
            {
                dataBuffer[StartingIndex++] = 0;
            }
        }

        private void FormatUint(byte[] dataBuffer,
                                ref uint StartingIndex,
                                uint DataValue)
        {
            dataBuffer[StartingIndex++] = (byte)((DataValue) & 0xFF);
            dataBuffer[StartingIndex++] = (byte)((DataValue >> 8) & 0xFF);
            dataBuffer[StartingIndex++] = (byte)((DataValue >> 16) & 0xFF);
            dataBuffer[StartingIndex++] = (byte)((DataValue >> 24) & 0xFF);
        }

        internal IntPtr Add(uint Label, coeDataInterchange.FormatPacketType packet)
        {
            IntPtr packetArray = IntPtr.Zero;
            if ((packet.m_NumberItems > 0) && (!_packets.TryGetValue(Label, out packetArray)))
            {
                int sizeOfInterchangeStructure = (int)(52 + (packet.m_NumberItems * 52));
                packetArray = Marshal.AllocHGlobal(sizeOfInterchangeStructure);
                byte[] dataArray = new byte[sizeOfInterchangeStructure];
                // Format the byte array with the data
                uint dataArrayIndex = 0;
                FormatString(dataArray, ref dataArrayIndex, packet.m_Name);
                FormatUint(dataArray, ref dataArrayIndex, packet.m_NumberItems);
                FormatUint(dataArray, ref dataArrayIndex, packet.m_DataByteSize);
                FormatUint(dataArray, ref dataArrayIndex, (uint)((IntPtr)(packetArray.ToInt32() + 52)));
                for (int count = 0; count < packet.m_NumberItems; count++)
                {
                    FormatString(dataArray, ref dataArrayIndex, packet.m_Format[count].m_FieldName);
                    FormatUint(dataArray, ref dataArrayIndex, packet.m_Format[count].m_Repetition);
                    FormatUint(dataArray, ref dataArrayIndex, packet.m_Format[count].m_FormatLength);
                    FormatUint(dataArray, ref dataArrayIndex, packet.m_Format[count].m_Format);
                }
                Marshal.Copy(dataArray, 0, packetArray, sizeOfInterchangeStructure);
                _packets.Add(Label, packetArray);
            }
            return packetArray;
        }
    }
}

//\\<Unclassified>
//----------------------------------------------------------------------------//
//                                 UNCLASSIFIED                               //
//----------------------------------------------------------------------------//
//\\<\Unclassified>

