using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

using SMath.Manager;
using SMath.Control;

namespace ImageFileType
{
    public class ImageFileType : IPluginSaveFileTypes
    {
        #region Private fields

        AssemblyInfo[] dependences;
        FileType[] fileTypesHandled;

        #endregion

        #region IPluginSaveFileTypes Members

        bool IPluginSaveFileTypes.SaveFileType(Stream stream, RegionsEnumerator enumerator, FileContext context)
        {
            // Checks if requested file type supported by plugin
            if (context.Extension == ".png" || context.Extension == ".bmp" || context.Extension == ".gif" || context.Extension == ".jpg")
            {
                // Creates an bitmap image with the required size
                Bitmap bmp = new Bitmap(context.WorksheetSize.Width, context.WorksheetSize.Height);
                
                // Creates an instance of the Graphics object to draw Regions on the bitmap
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    // Sets the background color of the result image
                    g.Clear(Color.White);

                    // Filter out every invisible Region (no need to draw Regions hidden by collapsed Areas)
                    enumerator.FilterInvisible = true;

                    // Iterate through all available Regions one by one
                    while (enumerator.MoveNext())
                    {
                        // Draws graphical representation of the worksheet Region (TopCorrection is a height of hidden by collapsed Area worksheet part above the Region)
                        enumerator.Current.DrawToBitmap(g, new Point(enumerator.Current.InnerBounds.Left, enumerator.Current.InnerBounds.Top - enumerator.TopCorrection));
                    }

                    ImageFormat format;
                    // Chooses a required image format to save the bitmap
                    switch (context.Extension)
                    {
                        case ".bmp": format = ImageFormat.Bmp; break;
                        case ".gif": format = ImageFormat.Gif; break;
                        case ".jpg": format = ImageFormat.Jpeg; break;
                        default: format = ImageFormat.Png; break;
                    }
                    
                    // height of page body
                    int pageHeight = context.PageModel.CanvasSize.Height;
                    
                    if (context.WorksheetSize.Height > pageHeight)
                    {
                    	int pages = context.WorksheetSize.Height / pageHeight;
                    	string baseName =  Path.GetFileNameWithoutExtension(context.Name);
                    	string leadingZerosFormat = "D" + (pages.ToString("D").Length + 1).ToString();
                    	
                    	for (int i = 0; i <= pages; i++)
                    	{
                    		int missingHeight = context.WorksheetSize.Height - i * pageHeight;
                    		Rectangle rect = new Rectangle(0, i * pageHeight, context.WorksheetSize.Width, Math.Min(missingHeight, pageHeight));
                    		Bitmap bmpChunk = bmp.Clone(rect, bmp.PixelFormat);
                    		
                    		// name of the image
                    		string filename = context.DirectoryName + baseName + "_" + (i+1).ToString(leadingZerosFormat) + context.Extension;
                    			
	                   		// Save the page as a single file
	                    	bmpChunk.Save(filename, format);
                    	}
                    }
                   	// Saves the entire bitmap to the Stream
                    bmp.Save(stream, format);
                }

                // Plugin successfully handled a file type
                return true;
            }

            // Plugin cannot handle requested file type
            return false;
        }

        #endregion

        #region IPluginHandleFileTypes Members

        FileType[] IPluginHandleFileTypes.FileTypesHandled
        {
            get { return this.fileTypesHandled; }
        }

        #endregion

        #region IPlugin Members

        AssemblyInfo[] IPlugin.Dependences
        {
            get { return this.dependences; }
        }

        void IPlugin.Initialize()
        {
            // Plugin requires SMath Studio 0.90 version for proper work
            this.dependences = new[] {
                new AssemblyInfo("SMath Studio", new Version(0, 90), new Guid("a37cba83-b69c-4c71-9992-55ff666763bd")),
            };
            // All file types that can be handled by plugin
            this.fileTypesHandled = new[] {
                new FileType("Image files", new[] { ".png", ".bmp", ".gif", ".jpg" }, FileBehavior.Save),
            };
        }

        #endregion

        #region IDisposable Members

        void IDisposable.Dispose()
        {
        }

        #endregion
    }
}
