// Thumbnailer.cs created with MonoDevelop
// User: klose at 15:23 15.06.2010
// CVS release: $Id: Thumbnailer.cs,v 1.2 2011-01-06 16:40:33 klose Exp $
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2009  Thomas Klose, Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

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

using Hiperscan.Spectroscopy;
using Hiperscan.Spectroscopy.IO;

using NPlot;


namespace Hiperscan.ThumbnailProvider
{

    public static class Thumbnailer
    {
        public static void CreatePng(Uri uri, string png_file, uint size)
        {
            Spectrum[] spectra = new Spectrum[0];
            Color color;
            string fname = Uri.UnescapeDataString(uri.AbsolutePath);
            
            CSV._IgnoreCorrection = true;
            
            if (Path.GetExtension(fname).ToLower() == ".csv")
            {
                spectra = new Spectrum[] { CSV.Read(fname) };
                color = Color.AntiqueWhite;
            }                
            else
            {
                spectra = CSV.ReadContainer(fname);
                color = Color.LightGreen;
            }

            Bitmap bmp = Thumbnailer.CreateThumbnailBitmap(spectra, 
                                                           color, 
                                                           (int)size,
                                                           (int)((double)size/1.618));
            bmp.Save(png_file, System.Drawing.Imaging.ImageFormat.Png);
        }
        
        internal static Bitmap CreateThumbnailBitmap(Spectrum[] spectra, Color background, int width, int height)
        {
            Bitmap bmp = new Bitmap(width, height);
            
            bool absorbance = true;
            foreach (Spectrum spectrum in spectra)
            {
                if (spectrum.HasAbsorbance == false)
                    absorbance = false;
            }

            PlotSurface2D ps = new PlotSurface2D
            {
                AutoScaleAutoGeneratedAxes = false,
                AutoScaleTitle = false,
                SmoothingMode  = System.Drawing.Drawing2D.SmoothingMode.AntiAlias,
                PlotBackColor  = Color.Transparent
            };

            double gxmin = double.MaxValue;
            double gxmax = double.MinValue;
            double gymin = double.MaxValue;
            double gymax = double.MinValue;
            
            foreach (Spectrum spectrum in spectra)
            {
                LinePlot lp = new LinePlot();
                DataSet ds;
                
                if (absorbance)
                    ds = spectrum.Absorbance;
                else
                    ds = spectrum.Intensity;
                
                double xmin = ds.XMin();
                double xmax = ds.XMax();
                double ymin = ds.YMin();
                double ymax = ds.YMax();
                if (xmin < gxmin) gxmin = xmin;
                if (xmax > gxmax) gxmax = xmax;
                if (ymin < gymin) gymin = ymin;
                if (ymax > gymax) gymax = ymax;
                
                lp.AbscissaData = ds.X;
                lp.OrdinateData = ds.Y;
                if (width < 80)
                    lp.Pen = new Pen(Color.Blue, 1f);
                else
                    lp.Pen = new Pen(Color.Blue, 2f);
                
                ps.Add(lp);
            }

            ps.XAxis1.WorldMin = gxmin;
            ps.XAxis1.WorldMax = gxmax;
            ps.YAxis1.WorldMin = gymin;
            ps.YAxis1.WorldMax = gymax;
            ps.XAxis1.Hidden = true;
            ps.YAxis1.Hidden = true;

            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(background);
                ps.Draw(g, new Rectangle(0, 0, width, height));

                Font font;
                if (width < 60)
                    font = new Font("Times", 12f, FontStyle.Regular, GraphicsUnit.Pixel);
                else
                    font = new Font("Times", (float)width/5f, FontStyle.Regular, GraphicsUnit.Pixel);
                Brush brush = new SolidBrush(Color.Black);
                PointF point = new PointF((float)(width / 30), (float)(width / 30));

                if (absorbance)
                    g.DrawString("A", font, brush, point);
                else
                    g.DrawString("I", font, brush, point);
            }
            
            return bmp;
        }
    }
}