using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

namespace CssSpriteGenerator
{
    public class FileSystem : IFileSystem 
    {
        // Path info that is the same for all requests
        
        // Url of the path to the sprites folder, with trailing /
        private string _resolvedUrlPath = null;

        // Full path on the file system of the sprites folder, with trailing \
        private string _fileSystemFolder = null;

        // ------------

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="generatedFolder">
        /// The sprites folder specified in the web.config.
        /// All methods in this class that write a file write to the file to this folder.
        /// </param>
        public FileSystem(string generatedFolder)
        {
            EnsureGeneratedFolder(generatedFolder, out _resolvedUrlPath, out _fileSystemFolder);
        }


        /// <summary>
        /// See IFileSystem
        /// </summary>
        public string WriteTextFile(string fileName, string fileContents)
        {
            string fileSystemPath = _fileSystemFolder + fileName;

            using (StreamWriter outfile = new StreamWriter(fileSystemPath))
            {
                outfile.Write(fileContents);
            }

            return _resolvedUrlPath + fileName;
        }


        /// <summary>
        /// See IFileSystem
        /// </summary>
        public string WriteImageFile(string fileName, Bitmap bitmap, ImageFormat imageFormat, int jpegQuality)
        {
            string fileSystemPath = _fileSystemFolder + fileName;

            if ((imageFormat != ImageFormat.Jpeg) || (jpegQuality == -1))
            {
                bitmap.Save(fileSystemPath, imageFormat);
            }
            else
            {
                ImageUtils.SaveJpgImage(bitmap, fileSystemPath, jpegQuality);
            }

            return _resolvedUrlPath + fileName;
        }


        /// <summary>
        /// See IFileSystem
        /// </summary>
        public string WriteImageFile(string fileName, Bitmap bitmap, ImageType imageType, int jpegQuality)
        {
            ImageFormat imageFormat = null;

            switch (imageType)
            {
                case ImageType.Gif:
                    imageFormat = ImageFormat.Gif;
                    break;

                case ImageType.Jpg:
                    imageFormat = ImageFormat.Jpeg;
                    break;

                case ImageType.Png:
                    imageFormat = ImageFormat.Png;
                    break;

                default:
                    throw new Exception(string.Format("Cannot convert ImageType {0} to ImageFormat", imageType));
            }

            return WriteImageFile(fileName, bitmap, imageFormat, jpegQuality);
        }


        /// <summary>
        /// Finds the url and file system path of the sprites folder, and stores them in
        /// _resolvedUrlPath
        /// _fileSystemFolder
        /// </summary>
        /// <param name="generatedFolder">
        /// The path from the root folder of the site to the sprites folder.
        /// This is part of a url, so use forward slashes if you want to use sub folders.
        /// 
        /// If the folder doesn't exist, it will be created by this method.
        /// </param>
        /// <param name="resolvedUrlPath">
        /// Url of the path to the sprites folder, with trailing /
        /// </param>
        /// <param name="fileSystemFolder">
        /// Full path on the file system of the sprites folder, with trailing \
        /// </param>
        private void EnsureGeneratedFolder(string generatedFolder, out string resolvedUrlPath, out string fileSystemFolder)
        {
            string physicalApplicationPath = HttpContext.Current.Request.PhysicalApplicationPath;
            string cleanedFolder = generatedFolder.Trim(new char[] { ' ', '\\', '/' });
            fileSystemFolder = physicalApplicationPath + @"\\" + cleanedFolder.Replace('/', '\\') + @"\\";

            Directory.CreateDirectory(fileSystemFolder);

            string tildeSpriteUrlPath = "~/" + cleanedFolder.Replace('\\', '/') + "/";
            resolvedUrlPath = VirtualPathUtility.ToAbsolute(tildeSpriteUrlPath);
        }
    }
}
