/**********************************************************************
zyGrib: meteorological GRIB file viewer
Copyright (C) 2008 - Jacques Zaninetti - http://www.zygrib.org

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/>.
***********************************************************************/

/*************************************
Dessin des données GRIB (avec QT)
*************************************/

#ifndef ISOLINE_H
#define ISOLINE_H

#include <iostream>
#include <cmath>
#include <vector>
#include <list>
#include <set>

#include "../../../include/ocpn_plugin.h"

#include "GribReader.h"

class ViewPort;
class wxDC;

class Segment;
WX_DECLARE_LIST(Segment, MySegList);
WX_DECLARE_LIST(MySegList, MySegListList);


//-------------------------------------------------------------------------------------------------------
//  Cohen & Sutherland Line clipping algorithms
//-------------------------------------------------------------------------------------------------------
/*
 * 
 * Copyright (C) 1999,2000,2001,2002,2003 Percy Zahl
 *
 * Authors: Percy Zahl <zahl@users.sf.net>
 * additional features: Andreas Klust <klust@users.sf.net>
 * WWW Home: http://gxsm.sf.net
 *
 */

typedef enum { Visible, Invisible } ClipResult;
typedef enum {
      LEFT, RIGHT, BOTTOM, TOP
} edge;
typedef long outcode;


void CompOutCode (double x, double y, outcode *code, struct LOC_cohen_sutherland_line_clip *LINK);
#ifdef __cplusplus
ClipResult cohen_sutherland_line_clip_d (double *x0, double *y0, double *x1, double *y1,
                                                     double xmin_, double xmax_, double ymin_, double ymax_);

extern "C"  ClipResult cohen_sutherland_line_clip_i (int *x0, int *y0, int *x1, int *y1,
                                                     int xmin_, int xmax_, int ymin_, int ymax_);

#endif


// TODO: join segments and draw a spline

//===============================================================
// Elément d'isobare qui passe dans un carré (ab-cd)de la grille.
// a  b
// c  d
// Rejoint l'arête (i,j)-(k,l) à l'arête (m,n)-(o,p) (indices ds la grille GRIB)

class Segment
{
    public:
        Segment (int I, int w, int J,
                char c1, char c2, char c3, char c4,
                const GribRecord *rec, double pressure);

        int   i,j,  k,l;   // arête 1
        double px1,  py1;   // Coordonées de l'intersection (i,j)-(k,l)
        int m,n, o,p;      // arête 2
        double px2,  py2;   // Coordonées de l'intersection (m,n)-(o,p)
        bool  bUsed;

    private:
        void traduitCode(int I, int w, int J, char c1, int &i, int &j);

        void intersectionAreteGrille(int i,int j, int k,int l,
                double *x, double *y,
                const GribRecord *rec, double pressure);
};

class GRIBOverlayFactory;
class TexFont;

//===============================================================
class IsoLine
{
    public:
         IsoLine(double val, double coeff, double offset, const GribRecord *rec);
        ~IsoLine();


        void drawIsoLine(GRIBOverlayFactory *pof, wxDC *dc, PlugIn_ViewPort *vp, bool bHiDef);

        void drawIsoLineLabels(GRIBOverlayFactory *pof, wxDC *dc,
                               PlugIn_ViewPort *vp, int density, int first,
                               wxImage &imageLabel);
        void drawIsoLineLabelsGL(GRIBOverlayFactory *pof, PlugIn_ViewPort *vp,
                                 int density, int first,
                                 wxString label, wxColour &color, TexFont &texfont);

        int getNbSegments()     {return trace.size();}

        double getValue() {return value;}
    private:
        double value;
        int    W, H;     // taille de la grille
        const  GribRecord *rec;

        wxColour  isoLineColor;
        std::list<Segment *> trace;


        void intersectionAreteGrille(int i,int j, int k,int l, double *x, double *y,
                        const GribRecord *rec);

        //-----------------------------------------------------------------------
        // Génère la liste des segments.
        // Les coordonnées sont les indices dans la grille du GribRecord
        //---------------------------------------------------------
        void extractIsoLine(const GribRecord *rec);
        MySegList *BuildContinuousSegment(void);

        MySegList       m_seglist;
        MySegListList   m_SegListList;
        
        double m_pixelMM;
};




#endif
