//>>> _using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.Windows;
//<<< _using
using System.IO;

namespace Framefield.Core.IDc4eb186c_29b7_4c68_b6c9_f8fbf91487bf
{
    public class Class_SkypeChatText : OperatorPart.Function
    {
        //>>> _inputids
        private enum InputId
        {
            RefreshTrigger = 0,
            FileSizeMin = 1,
            FileSizeMax = 2
        }
        //<<< _inputids

        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx)
        {
            //>>> _params
            var RefreshTrigger = inputs[(int)InputId.RefreshTrigger].Eval(context).Value;
            var FileSizeMin = inputs[(int)InputId.FileSizeMin].Eval(context).Value;
            var FileSizeMax = inputs[(int)InputId.FileSizeMax].Eval(context).Value;
            var FileSize = new Vector2(FileSizeMin, FileSizeMax);
            //<<< _params

            bool triggerUp = _lastTrigger < 0.5f && RefreshTrigger > 0.5f;
            _lastTrigger = RefreshTrigger;

            if (triggerUp) 
            {
                _minFileSize = (int)FileSizeMin;
                _maxFileSize = (int)FileSizeMax;
                
                try
                {
                    var directories = new List<String>()
                    {
                        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Skype\\",
                        Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\Skype\\",
                        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Skype\\"
                    };
    
                    foreach (var path in directories)
                        ScanDirectory(path);
                }
                catch
                {
                    Logger.Error(this, "error accessing directories");
                }
            }

            context.Text = _messages;
            return context;
        }

        private void ScanDirectory(String path)
        {
            if (path.IndexOf("chat") >= 0)
            {
                foreach (var filename in Directory.GetFiles(path))
                {
                    var basename = filename.Split('\\').Last();
                    var filepath = path + "/" + basename;
                    FileInfo f = new FileInfo(filepath);
    	            
    	            if (f.Length > _minFileSize && f.Length < _maxFileSize && File.Exists(filename))
    	            {
    	               collectMessages(filepath);
    	            }
                }
            }
            foreach (var dir in Directory.GetDirectories(path))
            {
                var dirname = dir.Split('\\').Last();
                ScanDirectory(path + "/" + dirname);
            }
        }

        public void collectMessages(string filePath)
        {
            FileStream stream = null;
            try
            {
                stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                byte[] bytes = new byte[(int)stream.Length];
                stream.Read(bytes, 0, (int)stream.Length);

                int offset = 0;
                while (offset != -1 && offset < (int)stream.Length)
                {
                    int startIdx = Find(bytes, _startMessageMarker, offset, (int)bytes.Length - offset);
                    int endIdx = FindFirstNotLetter(bytes, startIdx + _startMessageMarker.Length);
                    offset = endIdx;
                    int length = endIdx - startIdx;
                    if (startIdx >= 0 && length > 10)
                    {
                        byte[] subArray = new byte[length - _startMessageMarker.Length - 2];
                        Array.Copy(bytes, startIdx + _startMessageMarker.Length, subArray, 0, length - _startMessageMarker.Length - 2);
                        _messages += "\n" + Encoding.ASCII.GetString(subArray);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Error(this, "error: {0}", e.Message);
            }
            finally
            {
                Utilities.DisposeObj(ref stream);
            }
        }

        public static int Find(byte[] array, byte[] needle, int startIndex, int sourceLength)
        {
            int needleLen = needle.Length;
            int index;

            while (sourceLength >= needleLen)
            {
                index = Array.IndexOf(array, needle[0], startIndex, sourceLength - needleLen + 1);
                if (index == -1)
                    return -1;

                int i, p;
                for (i = 0, p = index; i < needleLen; i++, p++)
                {
                    if (array[p] != needle[i])
                        break;
                }

                if (i == needleLen)
                    return index;

                sourceLength -= (index - startIndex + 1);
                startIndex = index + 1;
            }
            return -1;
        }

        public static int FindFirstNotLetter(byte[] array, int startIndex)
        {
            int i = 0;
            while (startIndex + i < array.Length &&
                   array[startIndex + i] >= 32 && array[startIndex + i] < 123)
            {
                ++i;
            }
            if (startIndex + i >= array.Length)
                return -1;
            return startIndex + i;
        }

        byte[] _startMessageMarker = new byte[4] {0x47, 0x01, 0x03, 0x02};

        float _lastTrigger = 0.0f;
        private int _minFileSize;
        private int _maxFileSize;
        
        string _messages;
    }
}

