// Created with MonoDevelop
//
//    Copyright (C) 2010 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.Collections.Generic;
using System.Drawing;

using Gtk;

using Hiperscan.NPlotEngine.Overlay;
using Hiperscan.NPlotEngine.Overlay.Annotation;
using Hiperscan.NPlotEngine.Overlay.Selection;
using Hiperscan.Spectroscopy;

using Rectangle = System.Drawing.Rectangle;


namespace Hiperscan.NPlotEngine
{

    public enum PlotEngineType
    {
        Normal,
        Synchronous,
        Preview
    }

    public enum BackgroundType
    {
        Unchanged,
        Grayscaled,
        Dashed
    }

    public interface IPlotEngine
    {
        event EventHandler<EventArgs> Refreshed;
        event EventHandler<EventArgs> DataSetAdded;
        event EventHandler<EventArgs> DataSetRemoved;
        event EventHandler<EventArgs> DataSetsChanged;
        event EventHandler<EventArgs> PlotChanged;
        event EventHandler<EventArgs> PlotCreated;
        event EventHandler<EventArgs> AutoRemoveLegend;
        event EventHandler<EventArgs> XAxesReversed;
        
        float DefaultLineWidth { get; set; }
        
        double YExtendFactor { get; set; }
        double YMinRange     { get; set; }
        
        Gdk.Color BackgroundColor { get; set; }
        
        bool IsEmpty { get; }
        bool IsValid { get; }
        
        double GlobalXMin { get; }
        double GlobalXMax { get; }
        double GlobalYMin { get; }
        double GlobalYMax { get; }
        double ExtendedGlobalXMin { get; }
        double ExtendedGlobalXMax { get; }
        double ExtendedGlobalYMin { get; }
        double ExtendedGlobalYMax { get; }
        
        int PhysicalXMin { get; }
        int PhysicalXMax { get; }
        int PhysicalYMin { get; }
        int PhysicalYMax { get; }
        
        bool LockAxes { get; set; }
        
        double XMin { get; set; }
        double XMax { get; set; }
        double YMin { get; set; }
        double YMax { get; set; }
        
        string Title  { get; set; }
        string XLabel { get; set; }
        string YLabel { get; set; }
        
        int Width  { get; }
        int Height { get; }
        
        bool IsDragging { get; set; }
        bool DisableSelections { get; set; }
        bool LegendVisible { get; set; }
        bool UseSecondAxes { get; set; }
        bool ReverseXAxes { get; set; }
        bool HasBackgroundPlot { get; }
        
        double EstimatedLegendHeight { get; }
        
        Gdk.Pixbuf Thumbnail { get; }
        
        Dictionary<string,DataSet> DataSets { get; set; }
        
        List<CrossHair> Markers { get; }
        List<Annotation> Annotations { get; }
        List<DataSetSelection> DataSetSelections { get; }
        
        Rectangle Bounds { get; }
        RubberBandSelection Selection  { get; set; }
        HorizontalSelection HSelection { get; set; }
        VerticalSelection   VSelection { get; set; }
        
        Widget GtkWidget { get; }
        
        int PlotTypeId { get; set; }
        
        void Refresh();
        void Refresh(bool only_overlays);
        void AsyncRefresh();
        void AsyncRefresh(bool only_overlays);
        void Clear();
        void FitView();
        void RequestUpdate();
        void AddDataSet(DataSet ds);
        void ProcessChanges();
        void NotifyPlotChanges();
        
        void SetBackgroundPlot(IPlotEngine plot, BackgroundType bg_type);
        void ClearBackgroundPlot();
        void SyncAxes();
        
        void SetGlobalXMinMax(double x_min, double x_max);
        void SetGlobalXMinMax(double x_min, double x_max, bool force);
        void SetGlobalYMinMax(double x_min, double x_max);
        void SetSelection(int x, int y, int width, int height);
        void SetXAxis(double pan, double zoom);
        void SetYAxis(double pan, double zoom);
        void GetXMinMax(double pan, double zoom, out double min, out double max);
        void GetYMinMax(double pan, double zoom, out double min, out double max);
        
        double GetWorldXCoord(int x);
        double GetWorldYCoord(int y);
        double GetWorldXCoord(int x, bool clip);
        double GetWorldYCoord(int y, bool clip);
        int GetPhysicalXCoord(double x);
        int GetPhysicalYCoord(double y);
        int GetPhysicalXCoord(double x, bool clip);
        int GetPhysicalYCoord(double y, bool clip);
        
        Bitmap GetBitmap();
        Bitmap GetBitmap(int width, int height);
        Bitmap GetBitmap(float xdpi, float ydpi);
        Bitmap GetBitmap(int width, int height, float xdpi, float ydpi);
        
        Gdk.Pixbuf GetPixbuf();
        Gdk.Pixbuf GetPixbuf(int width, int height);
        Gdk.Pixbuf GetPixbuf(float xdpi, float ydpi);
        Gdk.Pixbuf GetPixbuf(int width, int height, float xdpi, float ydpi);
        Gdk.Pixbuf GetLineStylePixbuf(Spectrum spectrum);
        Gdk.Pixbuf GetLineStylePixbuf(LineStyle style);
        Gdk.Pixbuf GetLineStylePixbuf(CapStyle style);
        
        Cairo.Context GetCairoContext();
        Cairo.Surface GetCairoSurface();
        
        void StartAutoUpdate();
        void StopAutoUpdate();
        
        void Draw(Graphics g, System.Drawing.Rectangle bounds);
        void DrawOverlays(Graphics g, bool only_static_overlays);
        void DrawLegend(Graphics g);
    }
}