//    CANAPE Network Testing Tool
//    Copyright (C) 2014 Context Information Security
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using CANAPE.Controls;
using CANAPE.Nodes;
using CANAPE.Utils;
namespace CANAPE.Forms
{
    internal partial class PacketLogViewerForm : Form
    {
        int _index;
        IList<LogPacket> _packets;
        PacketEntry[] _modifiedPackets;
        bool _newStyleLogViewer;
        private struct PacketEntry
        {
            public bool modified;
            public LogPacket packet;
        }
        public bool ReadOnly { get; set; }
        private bool IsFrameModified()
        {
            if (_packets.Count == 0)
            {
                return false;
            }
            return _modifiedPackets[_index].modified;
        }
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            bool ret = true;
            switch(keyData)
            {
                case Keys.Control | Keys.N:
                    toolStripButtonForward.PerformClick();
                    break;
                case Keys.Control | Keys.P:
                    toolStripButtonBack.PerformClick();
                    break;                    
                case Keys.Control | Keys.S:
                    if (_newStyleLogViewer && IsFrameModified())
                    {
                        toolStripButtonSave.PerformClick();
                    }
                    break;
                default:
                    ret = base.ProcessCmdKey(ref msg, keyData);
                    break;
            }
            return ret;
        }
        public PacketLogViewerForm(LogPacket curr, IList<LogPacket> packets)
        {
            for (int i = 0; i < packets.Count; i++)
            {
                if (packets[i] == curr)
                {
                    _index = i;
                    break;
                }
            }
            
            _packets = packets;
            _modifiedPackets = new PacketEntry[_packets.Count];
            _newStyleLogViewer = GlobalControlConfig.NewStyleLogViewer;
            
            InitializeComponent();
            timer.Start();
        }
        private void SetModifiedFrame()
        {
            _modifiedPackets[_index].modified = false;
            _modifiedPackets[_index].packet = _packets[_index].ClonePacket();
            _modifiedPackets[_index].packet.Frame.FrameModified += new EventHandler(_currPacket_FrameModified);
        }
        private LogPacket GetCurrentPacket()
        {
            if (_packets.Count == 0)
            {
                return null;
            }
            if (_newStyleLogViewer)
            {
                if (_modifiedPackets[_index].packet == null)
                {
                    SetModifiedFrame();
                }
                return _modifiedPackets[_index].packet;
            }
            else
            {
                return _packets[_index];
            }
        }
        private void OnFrameModified()
        {
            _modifiedPackets[_index].modified = true;
            toolStripButtonSave.Enabled = true;
            toolStripButtonRevert.Enabled = true;
        }
        void _currPacket_FrameModified(object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(OnFrameModified));
            }
            else
            {
                OnFrameModified();
            }
        }
        private void UpdatePacketDisplay()
        {
            LogPacket p = GetCurrentPacket();
            if (p == null)
            {
                return;
            }
            if (!_newStyleLogViewer)
            {
                frameEditorControl.ReadOnly = ReadOnly;
            }
            frameEditorControl.SetFrame(p.Frame, null, ColorValueConverter.ToColor(p.Color));
            if (p.Frame.IsBasic || (ReadOnly && !_newStyleLogViewer))
            {
                toolStripButtonConvertToBytes.Enabled = false;
            }
            else
            {
                toolStripButtonConvertToBytes.Enabled = true;
            }
            if (_newStyleLogViewer)
            {
                toolStripButtonSave.Enabled = IsFrameModified();
                toolStripButtonRevert.Enabled = IsFrameModified();
            }
            toolStripLabelPosition.Text = String.Format(CANAPE.Properties.Resources.PacketLogViewerForm_Header, _index + 1, 
                _packets.Count, p.Tag, p.Network, p.Timestamp.ToString());
        }
        private void LogViewerForm_Load(object sender, EventArgs e)
        {
            if(_packets.Count == 0)
            {
                Close();
            }
            if (!_newStyleLogViewer)
            {
                Text = !ReadOnly ? CANAPE.Properties.Resources.PacketLogViewerForm_Title
                        : CANAPE.Properties.Resources.PacketLogViewerForm_TitleReadOnly;
                toolStripButtonSave.Visible = false;
                toolStripButtonRevert.Visible = false;
            }
            else
            {
                Text = CANAPE.Properties.Resources.PacketLogViewerForm_Title;
            }
            UpdatePacketDisplay();
        }
        private void toolStripButtonBack_Click(object sender, EventArgs e)
        {           
            _index -= 1;
            if (_index < 0)
            {
                _index = _packets.Count - 1;
            }
            UpdatePacketDisplay();
        }
        private void toolStripButtonForward_Click(object sender, EventArgs e)
        {           
            _index++;
            if (_index > _packets.Count - 1)
            {
                _index = 0;
            }
            UpdatePacketDisplay();
        }
        private void toolStripButtonCopy_Click(object sender, EventArgs e)
        {
            LogPacket currPacket = GetCurrentPacket();


Answer:             if (currPacket != null)