using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Imaging;
using System.IO;
using System.Drawing;
using Schematrix;
using Mall.Education.Helper;
using System.Net;

namespace Mall.Education.Offices
{
    /*  
     * 
     * 将pdf、ppf、word转换给图片的组件有很多，这里仅使用Aspose组件（试用版）作为示例。
     * 
     * Aspose官网：www.aspose.com， 请支持和购买正版Aspose组件。
     * 
     */


    #region 将word文档转换为图片
    public class Word2ImageConverter 
    {
        private bool cancelled = false;

        public void Cancel()
        {
            if (this.cancelled)
            {
                return;
            }

            this.cancelled = true;
        }

        public void ConvertToImage(string originFilePath, string imageOutputDirPath, ImageFormat imageFormat, out int PageNum)
        {
            this.cancelled = false;
            ConvertToImage(originFilePath, imageOutputDirPath, 0, 0, imageFormat, 200, out PageNum);
        }

        /// <summary>
        /// 从网站上下载pdf，转化为字节流
        /// </summary>
        /// <param name="srcPdfFile">文件地址：'https://******/group2/M00/00/04/wKj-mlpcoZ2IUbK5AACrpaV6k98AAAB6gAAAAAAAKu9562.pdf'</param>
        /// <returns></returns>
        public static string GetByteByRemoteURL(string srcPdfFile,string fileName)
        {
            try
            {
                byte[] arraryByte;
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(srcPdfFile);
                req.Method = "GET";
                using (WebResponse wr = req.GetResponse())
                {
                    StreamReader responseStream = new StreamReader(wr.GetResponseStream(), Encoding.UTF8);
                    int length = (int)wr.ContentLength;
                    byte[] bs = new byte[length];

                    HttpWebResponse response = wr as HttpWebResponse;
                    Stream stream = response.GetResponseStream();

                    //读取到内存
                    MemoryStream stmMemory = new MemoryStream();
                    byte[] buffer1 = new byte[length];
                    int i;
                    //将字节逐个放入到Byte 中
                    while ((i = stream.Read(buffer1, 0, buffer1.Length)) > 0)
                    {
                        stmMemory.Write(buffer1, 0, i);
                    }
                    arraryByte = stmMemory.ToArray();
                    stmMemory.Close();
                }
                StreamToFile(arraryByte, fileName);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return "";
            }
            return fileName;
        }

        /// <summary>
        /// 流转文件
        /// </summary>
        /// <param name="arraryByte"></param>
        /// <param name="fileName"></param>
        public static void StreamToFile(byte[] arraryByte, string fileName)
        {
            // 把 byte[] 写入文件
            FileStream fs = new FileStream(fileName, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(arraryByte);
            bw.Close();
            fs.Close();
        }

        /// <summary>
        /// 将Word文档转换为图片的方法      
        /// </summary>
        /// <param name="wordInputPath">Word文件路径</param>
        /// <param name="imageOutputDirPath">图片输出路径，如果为空，默认值为Word所在路径</param>      
        /// <param name="startPageNum">从PDF文档的第几页开始转换，如果为0，默认值为1</param>
        /// <param name="endPageNum">从PDF文档的第几页开始停止转换，如果为0，默认值为Word总页数</param>
        /// <param name="imageFormat">设置所需图片格式，如果为null，默认格式为PNG</param>
        /// <param name="resolution">设置图片的像素，数字越大越清晰，如果为0，默认值为128，建议最大值不要超过1024</param>
        private void ConvertToImage(string wordInputPath, string imageOutputDirPath, int startPageNum, int endPageNum, ImageFormat imageFormat, int resolution,out int PageNum)
        {
            PageNum = 0;
            try
            {
                //var localfile = GetByteByRemoteURL(wordInputPath, imageOutputDirPath + Path.GetFileName(wordInputPath));
                //if (localfile == "") {
                //    return;
                //}
                Aspose.Words.Document doc = new Aspose.Words.Document(wordInputPath);

                if (doc == null)
                {
                    throw new Exception("Word文件无效或者Word文件被加密！");
                }

                if (imageOutputDirPath.Trim().Length == 0)
                {
                    imageOutputDirPath = Path.GetDirectoryName(wordInputPath);
                }

                if (!Directory.Exists(imageOutputDirPath))
                {
                    Directory.CreateDirectory(imageOutputDirPath);
                }               

                if (startPageNum <= 0)
                {
                    startPageNum = 1;
                }

                if (endPageNum > doc.PageCount || endPageNum <= 0)
                {
                    endPageNum = doc.PageCount;
                }

                if (startPageNum > endPageNum)
                {
                    int tempPageNum = startPageNum; startPageNum = endPageNum; endPageNum = startPageNum;
                }
                PageNum = endPageNum;
                if (imageFormat == null)
                {
                    imageFormat = ImageFormat.Png;
                }

                if (resolution <= 0)
                {
                    resolution = 128;
                }

                string imageName = Path.GetFileNameWithoutExtension(wordInputPath);
                Aspose.Words.Saving.ImageSaveOptions imageSaveOptions = new Aspose.Words.Saving.ImageSaveOptions(Aspose.Words.SaveFormat.Png);
                imageSaveOptions.Resolution = resolution;
                for (int i = startPageNum; i <= endPageNum; i++)
                {
                    if (this.cancelled)
                    {
                        break;
                    }

                    MemoryStream stream = new MemoryStream();
                    imageSaveOptions.PageIndex = i - 1;
                    string imgPath = Path.Combine(imageOutputDirPath, imageName) + "_" + i.ToString("000") + "." + imageFormat.ToString();
                    doc.Save(stream, imageSaveOptions);
                    Image img = Image.FromStream(stream);
                    Bitmap bm = (Bitmap)img;
                    bm.Save(imgPath, imageFormat);
                    img.Dispose();
                    stream.Dispose();
                    bm.Dispose();

                    System.Threading.Thread.Sleep(200);
                }

                if (this.cancelled)
                {
                    return;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                LogHelper.Write(ex, "word转图片");
            }
        }
    }
    #endregion

    #region 将pdf文档转换为图片
    public class Pdf2ImageConverter
    {
        private bool cancelled = false;

        public void Cancel()
        {
            if (this.cancelled)
            {
                return;
            }

            this.cancelled = true;
        }

        public void ConvertToImage(string originFilePath, string imageOutputDirPath, ImageFormat imageFormat, out int PageNum, bool IsNotLocal = true)
        {
            this.cancelled = false;
            ConvertToImage(originFilePath, imageOutputDirPath, 0, 0, imageFormat, 200, out PageNum, IsNotLocal);
        }

        /// <summary>
        /// 将pdf文档转换为图片的方法      
        /// </summary>
        /// <param name="originFilePath">pdf文件路径</param>
        /// <param name="imageOutputDirPath">图片输出路径，如果为空，默认值为pdf所在路径</param>       
        /// <param name="startPageNum">从PDF文档的第几页开始转换，如果为0，默认值为1</param>
        /// <param name="endPageNum">从PDF文档的第几页开始停止转换，如果为0，默认值为pdf总页数</param>       
        /// <param name="resolution">设置图片的像素，数字越大越清晰，如果为0，默认值为128，建议最大值不要超过1024</param>
        private void ConvertToImage(string originFilePath, string imageOutputDirPath, int startPageNum, int endPageNum, ImageFormat imageFormat, int resolution, out int PageNum,bool IsNotLocal = true)
        {
            PageNum = 0;
            try
            {
                if (IsNotLocal) {
                    //生成本地文件
                    var localfile = GetByteByRemoteURL(originFilePath, imageOutputDirPath + Path.GetFileName(originFilePath));
                    if (localfile == "")
                    {
                        return;
                    }
                    originFilePath = localfile;
                }
                Aspose.Pdf.Document doc = new Aspose.Pdf.Document(originFilePath);

                if (doc == null)
                {
                    throw new Exception("pdf文件无效或者pdf文件被加密！");
                }

                if (imageOutputDirPath.Trim().Length == 0)
                {
                    imageOutputDirPath = Path.GetDirectoryName(originFilePath);
                }

                if (!Directory.Exists(imageOutputDirPath))
                {
                    Directory.CreateDirectory(imageOutputDirPath);
                }

                if (startPageNum <= 0)
                {
                    startPageNum = 1;
                }
                if (endPageNum > doc.Pages.Count || endPageNum <= 0)
                {
                    endPageNum = doc.Pages.Count;
                }

                if (startPageNum > endPageNum)
                {
                    int tempPageNum = startPageNum; startPageNum = endPageNum; endPageNum = startPageNum;
                }
                PageNum = endPageNum;
                if (resolution <= 0)
                {
                    resolution = 128;
                }

                string imageNamePrefix = Path.GetFileNameWithoutExtension(originFilePath);
                for (int i = startPageNum; i <= endPageNum; i++)
                {
                    if (this.cancelled)
                    {
                        break;
                    }

                    MemoryStream stream = new MemoryStream();
                    string imgPath = Path.Combine(imageOutputDirPath, imageNamePrefix) + "_" + i.ToString("000") + "." + imageFormat.ToString();
                    Aspose.Pdf.Devices.Resolution reso = new Aspose.Pdf.Devices.Resolution(resolution);
                    Aspose.Pdf.Devices.JpegDevice jpegDevice = new Aspose.Pdf.Devices.JpegDevice(reso, 100);
                    jpegDevice.Process(doc.Pages[i], stream);

                    Image img = Image.FromStream(stream);
                    Bitmap bm = (Bitmap)img;
                    bm.Save(imgPath, imageFormat);
                    img.Dispose();
                    stream.Dispose();
                    bm.Dispose();

                    System.Threading.Thread.Sleep(200);
                }

                if (IsNotLocal) {
                    File.Delete(originFilePath);
                }
                if (this.cancelled)
                {
                    return;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                LogHelper.Write(ex, "pdf转图片");
            }
        }

        /// <summary>
        /// 从网站上下载pdf，转化为字节流
        /// </summary>
        /// <param name="srcPdfFile">文件地址：'https://******/group2/M00/00/04/wKj-mlpcoZ2IUbK5AACrpaV6k98AAAB6gAAAAAAAKu9562.pdf'</param>
        /// <returns></returns>
        public static string GetByteByRemoteURL(string srcPdfFile, string fileName)
        {
            try
            {
                byte[] arraryByte;
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(srcPdfFile);
                req.Method = "GET";
                using (WebResponse wr = req.GetResponse())
                {
                    StreamReader responseStream = new StreamReader(wr.GetResponseStream(), Encoding.UTF8);
                    int length = (int)wr.ContentLength;
                    byte[] bs = new byte[length];

                    HttpWebResponse response = wr as HttpWebResponse;
                    Stream stream = response.GetResponseStream();

                    //读取到内存
                    MemoryStream stmMemory = new MemoryStream();
                    byte[] buffer1 = new byte[length];
                    int i;
                    //将字节逐个放入到Byte 中
                    while ((i = stream.Read(buffer1, 0, buffer1.Length)) > 0)
                    {
                        stmMemory.Write(buffer1, 0, i);
                    }
                    arraryByte = stmMemory.ToArray();
                    stmMemory.Close();
                }
                StreamToFile(arraryByte, fileName);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return "";
            }
            return fileName;
        }

        /// <summary>
        /// 流转文件
        /// </summary>
        /// <param name="arraryByte"></param>
        /// <param name="fileName"></param>
        public static void StreamToFile(byte[] arraryByte, string fileName)
        {
            // 把 byte[] 写入文件
            FileStream fs = new FileStream(fileName, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(arraryByte);
            bw.Close();
            fs.Close();
        }
    }
    #endregion

    #region 将ppt文档转换为图片
    public class Ppt2ImageConverter
    {
        private Pdf2ImageConverter pdf2ImageConverter;

        public void Cancel()
        {
            if (this.pdf2ImageConverter != null)
            {
                this.pdf2ImageConverter.Cancel();
            }
        }

        public void ConvertToImage(string originFilePath, string imageOutputDirPath, ImageFormat imageFormat, out int PageNum)
        {
            ConvertToImage(originFilePath, imageOutputDirPath, 0, 0, 200, imageFormat, out PageNum);
        }

        /// <summary>
        /// 将pdf文档转换为图片的方法      
        /// </summary>
        /// <param name="originFilePath">ppt文件路径</param>
        /// <param name="imageOutputDirPath">图片输出路径，如果为空，默认值为pdf所在路径</param>       
        /// <param name="startPageNum">从PDF文档的第几页开始转换，如果为0，默认值为1</param>
        /// <param name="endPageNum">从PDF文档的第几页开始停止转换，如果为0，默认值为pdf总页数</param>       
        /// <param name="resolution">设置图片的像素，数字越大越清晰，如果为0，默认值为128，建议最大值不要超过1024</param>
        private void ConvertToImage(string originFilePath, string imageOutputDirPath, int startPageNum, int endPageNum, int resolution, ImageFormat imageFormat, out int PageNum)
        {
            PageNum = 0;
            try
            {
                //生成本地文件
                var localfile = GetByteByRemoteURL(originFilePath, imageOutputDirPath + Path.GetFileName(originFilePath));
                if (localfile == "")
                {
                    return;
                }
                Aspose.Slides.Presentation doc = new Aspose.Slides.Presentation(localfile);

                if (doc == null)
                {
                    throw new Exception("ppt文件无效或者ppt文件被加密！");
                }

                if (imageOutputDirPath.Trim().Length == 0)
                {
                    imageOutputDirPath = Path.GetDirectoryName(localfile);
                }

                if (!Directory.Exists(imageOutputDirPath))
                {
                    Directory.CreateDirectory(imageOutputDirPath);
                }

                if (resolution <= 0)
                {
                    resolution = 128;
                }

                //先将ppt转换为pdf临时文件
                string tmpPdfPath = localfile.Replace(".ppt", "").Replace(".pptx", "") + ".pdf";
                doc.Save(tmpPdfPath, Aspose.Slides.Export.SaveFormat.Pdf);

                //再将pdf转换为图片
                Pdf2ImageConverter converter = new Pdf2ImageConverter();
                converter.ConvertToImage(tmpPdfPath, imageOutputDirPath, imageFormat, out PageNum, false);

                //删除pdf临时文件
                File.Delete(tmpPdfPath);
                File.Delete(localfile);
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "ppt转图片");
            }

            this.pdf2ImageConverter = null;
        }

        /// <summary>
        /// 从网站上下载pdf，转化为字节流
        /// </summary>
        /// <param name="srcPdfFile">文件地址：'https://******/group2/M00/00/04/wKj-mlpcoZ2IUbK5AACrpaV6k98AAAB6gAAAAAAAKu9562.pdf'</param>
        /// <returns></returns>
        public static string GetByteByRemoteURL(string srcPdfFile, string fileName)
        {
            try
            {
                byte[] arraryByte;
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(srcPdfFile);
                req.Method = "GET";
                using (WebResponse wr = req.GetResponse())
                {
                    StreamReader responseStream = new StreamReader(wr.GetResponseStream(), Encoding.UTF8);
                    int length = (int)wr.ContentLength;
                    byte[] bs = new byte[length];

                    HttpWebResponse response = wr as HttpWebResponse;
                    Stream stream = response.GetResponseStream();

                    //读取到内存
                    MemoryStream stmMemory = new MemoryStream();
                    byte[] buffer1 = new byte[length];
                    int i;
                    //将字节逐个放入到Byte 中
                    while ((i = stream.Read(buffer1, 0, buffer1.Length)) > 0)
                    {
                        stmMemory.Write(buffer1, 0, i);
                    }
                    arraryByte = stmMemory.ToArray();
                    stmMemory.Close();
                }
                StreamToFile(arraryByte, fileName);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return "";
            }
            return fileName;
        }

        /// <summary>
        /// 流转文件
        /// </summary>
        /// <param name="arraryByte"></param>
        /// <param name="fileName"></param>
        public static void StreamToFile(byte[] arraryByte, string fileName)
        {
            // 把 byte[] 写入文件
            FileStream fs = new FileStream(fileName, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(arraryByte);
            bw.Close();
            fs.Close();
        }
    }
    #endregion

    #region 将图片压缩包解压。（如果课件本身就是多张图片，那么可以将它们压缩成一个rar，作为一个课件）
    /// <summary>
    /// 将图片压缩包解压。（如果课件本身就是多张图片，那么可以将它们压缩成一个rar，作为一个课件）
    /// </summary>
    public class Rar2ImageConverter 
    {
        private bool cancelled = false;

        public void Cancel()
        {
            this.cancelled = true;
        }


        public void ConvertToImage(string rarPath, string imageOutputDirPath)
        {
            try
            {
                Unrar tmp = new Unrar(rarPath);
                tmp.Open(Unrar.OpenMode.List);
                string[] files = tmp.ListFiles();
                tmp.Close();

                int total = files.Length;
                int done = 0;

                Unrar unrar = new Unrar(rarPath);
                unrar.Open(Unrar.OpenMode.Extract);
                unrar.DestinationPath = imageOutputDirPath;

                while (unrar.ReadHeader() && !cancelled)
                {
                    if (unrar.CurrentFile.IsDirectory)
                    {
                        unrar.Skip();
                    }
                    else
                    {
                        unrar.Extract();
                        ++done;
                    }
                }
                unrar.Close();
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "转图片压缩失败");
            }
        }

        
    } 
    #endregion
}
