//>>> _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;
using System.Dynamic;
using System.Text.RegularExpressions;
using System.Drawing;

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

        //>>> _outputids
        private enum OutputId
        {
            Dynamic = 0,
            Count = 1
        }
        //<<< _outputids



        
        static bool IsImage(string filePath)
        {
            if (! File.Exists(filePath) )
                return false;            
            
            //FileStream stream;
            try {
                //stream =    new FileStream(filePath, FileMode.Open, FileAccess.Read);
                var newImage = System.Drawing.Image.FromFile(filePath);
                newImage.Dispose();
            }
            catch {
                return false;
            }

            return true;//IsValidImage(stream);
        }
        
        static bool IsValidImage(Stream imageStream)
        {
            if(imageStream.Length > 0)
            {
                byte[] header = new byte[4]; // Change size if needed.
                string[] imageHeaders = new[]{
                    Encoding.ASCII.GetString(new byte[]{0xFF, 0xd8,}),  // JPEG
                        "BM",       // BMP
                        "GIF",      // GIF
                        Encoding.ASCII.GetString(new byte[]{137, 80, 78, 71})}; // PNG
                try {
                    imageStream.Read(header, 0, header.Length);
                }
                catch {
                    return false;
                }
        
                return imageHeaders.Count(str => Encoding.ASCII.GetString(header).StartsWith(str)) > 0;
            }
        
            imageStream.Close();
            return false;
        }        
        

        private void ScanDirectory(String path) {
            try {
                foreach (var filename in Directory.GetFiles(path))
                {
                    if (_allFiles.Count > 100)
                        break;
                    var basename = filename.Split('\\').Last();
                    var filepath =path + "\\" + basename ;
                    FileInfo f = new FileInfo(filepath);
    	            long s1 = f.Length;
    	            
    	            if( f.Length > _minFileSize && f.Length < _maxFileSize  && IsImage(filepath)) {
    	               Logger.Info(this, "size {0}", f.Length);
    	               _allFiles.Add( filepath) ;
    	            }
                }
                foreach (var dir in Directory.GetDirectories(path)) {
                    var dirname= dir.Split('\\').Last();
                    ScanDirectory(path + "\\" + dirname);
                }
            }
            catch {
                Logger.Warn(this, "Can't read {0}", path);
            }
        }
        

        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) {
            //>>> _params
            var DirectoryPath = inputs[(int)InputId.DirectoryPath].Eval(context).Text;
            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

            if( _allFiles == null || RefreshTrigger > 0.5f) 
            {
            
                _minFileSize = (int)FileSizeMin;
                _maxFileSize = (int)FileSizeMax;
                
                var directories = new List<String>() {
                    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Google\\Chrome\\User Data\\Default\\Cache"  ,
                    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Microsoft\\Windows\\Temporary Internet Files\\Content.IE5",
                    "c:\\Windows\\Web\\Wallpaper"
                };

                _allFiles = new List<String>();

                foreach( var path in directories) {
                    ScanDirectory( path);
                }

                if (_allFiles.Count < 20)
                {
                    ScanDirectory(".\\assets-new\\images\\fallback");
                }
                
                Random rng = new Random((int)DateTime.Now.Ticks);
                _allFiles = _allFiles.OrderBy(a => rng.Next()).ToList();
                
                foreach(var s in _allFiles) {
                    Logger.Info(s);
                }
            }

            
            switch(outputIdx) {
                case  (int)OutputId.Dynamic:
                    context.Dynamic = _allFiles;
                    break;
                case  (int)OutputId.Count:
                    context.Value = _allFiles.Count;    // FIXME: This is never called?
                    break;
            }
            //context.Value = _allFiles.Count;
            return context;
            
         
        }
        
        private string _directoryPath;
        private List<String>  _allFiles;
        private int _minFileSize;
        private int _maxFileSize;

        
    }
}

