/////////////////////////////////////////////////////////////////////////////////
//
// This file is part of SACAMOS, cable models for EMI simulations in SPICE.
// It was developed by the University of Nottingham and the Netherlands Aerospace
// Centre (NLR) for ESA under contract number 4000112765/14/NL/HK.
//
// Copyright (C) 2015 - 2018 University of Nottingham
//
// SACAMOS 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.
//
// SACAMOS 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.
//
// A copy of the GNU General Public License version 3 can be found in the
// file GNU_GPL_v3 in the root or at <http://www.gnu.org/licenses/>.
//
// wxWidgets is currently licenced under the "wxWindows Library Licence".
// A copy of the wxWindows Library Licence, Version 3.1 can be found in the file
// wxWindows_Library_Licence_v3-1 in the root or at:
// <https://www.wxwidgets.org/about/licence/>
//
// The University of Nottingham can be contacted at: ggiemr@nottingham.ac.uk
//
// File Contents:
//
// NAME
//     MESH_LAPLACE.cpp
//
// DESCRIPTION
//     GUI for displaying Laplace solver mesh
//
// AUTHOR(S)
//     Steve Greedy
//
/////////////////////////////////////////////////////////////////////////////////
#include "MESH_LAPLACE.h"


void draw_mesh(wxPanel *Panel, wxString mesh_to_draw)
{
    wxClientDC dc(Panel);
    dc.Clear();

    dc.SetTextForeground(*wxBLUE);
    dc.DrawText(("Laplace Mesh: " + mesh_to_draw) , 10, 15);

    mesh_to_draw = mesh_to_draw + ".msh.vtk";// + "_mesh_domain_1.msh.vtk";

    std::string str, points, polygons;

    int no_points, no_polygons;

    std::ifstream meshFile;
    meshFile.open (mesh_to_draw);

    std::getline(meshFile, str); //Read to end of line
    std::getline(meshFile, str); //Read to end of line
    std::getline(meshFile, str); //Read to end of line
    std::getline(meshFile, str); //Read to end of line
    meshFile >>points >>no_points;
    std::getline(meshFile, str); //Read to end of line

    float ** dataPoint;
    dataPoint = new float*[no_points];

    for (int i = 0; i< no_points; i++)
    {
        dataPoint[i] = new float[2];
    }

    for (int i = 0; i< no_points; i++)
    {
        meshFile >> dataPoint[i][0] >> dataPoint[i][1];
        std::getline(meshFile, str);
    }

    meshFile >> polygons >> no_polygons;
    std::getline(meshFile, str); //Read to end of line & position at start of Polygon list

    float xmin, xmax, ymin, ymax;

    xmin = 0;
    xmax = 0;
    ymin = 0;
    ymax = 0;

    for (int i = 0; i< no_points; i++)
    {
        if (dataPoint[i][0] > xmax) xmax = dataPoint[i][0];
        if (dataPoint[i][0] < xmin) xmin = dataPoint[i][0];
        if (dataPoint[i][1] > ymax) ymax = dataPoint[i][1];
        if (dataPoint[i][1] < ymin) ymin = dataPoint[i][1];
    }

    int size_h, size_v;
    float scale;

    Panel->GetSize(&size_h, &size_v );

    if (xmax-xmin > ymax-ymin) scale = size_h/(xmax-xmin);

        else scale = 0.75*(size_v/(ymax-ymin));

    dc.SetPen( wxPen( *wxBLUE));

    int i, polygon_edges, v1, v2, v3;

    v1 = 0;
    v2 = 1;
    v3 = 2;

    int h_polygons = no_polygons/2;

    //need to flip rows top to bottom to invert image...

    for (i = 0; i < no_polygons;i++)
    {
        meshFile >> polygon_edges >> v1 >> v2 >> v3;

        dc.DrawLine( dataPoint[v1][0]*scale+size_h/2,size_v - (dataPoint[v1][1]*scale+size_v/2), dataPoint[v2][0]*scale+size_h/2,size_v - (dataPoint[v2][1]*scale+size_v/2 ));

        dc.DrawLine( dataPoint[v2][0]*scale+size_h/2,size_v -  (dataPoint[v2][1]*scale+size_v/2), dataPoint[v3][0]*scale+size_h/2,size_v - (dataPoint[v3][1]*scale+size_v/2 ));

        dc.DrawLine( dataPoint[v3][0]*scale+size_h/2,size_v - (dataPoint[v3][1]*scale+size_v/2), dataPoint[v1][0]*scale+size_h/2, size_v - (dataPoint[v1][1]*scale+size_v/2 ));

        std::getline(meshFile, str);

    }

    meshFile.close();
}

void zoom_mesh(wxPanel *Panel, wxString mesh_to_draw)
{

    wxClientDC dc(Panel);
    dc.Clear();

    dc.SetTextForeground(*wxBLUE);
    dc.DrawText(("Laplace Mesh: " + mesh_to_draw) , 10, 15);

    mesh_to_draw = mesh_to_draw + "_mesh_domain_1.msh.vtk";

    std::string str, points, polygons;

    int no_points, no_polygons;

    std::ifstream meshFile;
    meshFile.open (mesh_to_draw);

    std::getline(meshFile, str); //Read to end of line
    std::getline(meshFile, str); //Read to end of line
    std::getline(meshFile, str); //Read to end of line
    std::getline(meshFile, str); //Read to end of line
    meshFile >>points >>no_points;
    std::getline(meshFile, str); //Read to end of line

    float ** dataPoint;
    dataPoint = new float*[no_points];

    for (int i = 0; i< no_points; i++)
    {
        dataPoint[i] = new float[2];
    }

    for (int i = 0; i< no_points; i++)
    {
        meshFile >> dataPoint[i][0] >> dataPoint[i][1];
        std::getline(meshFile, str);
    }

    meshFile >> polygons >> no_polygons;
    std::getline(meshFile, str); //Read to end of line & position at start of Polygon list

    float xmin, xmax, ymin, ymax;

    xmin = 0;
    xmax = 0;
    ymin = 0;
    ymax = 0;

    for (int i = 0; i< no_points; i++)
    {
        if (dataPoint[i][0] > xmax) xmax = dataPoint[i][0];
        if (dataPoint[i][0] < xmin) xmin = dataPoint[i][0];
        if (dataPoint[i][1] > ymax) ymax = dataPoint[i][1];
        if (dataPoint[i][1] < ymin) ymin = dataPoint[i][1];
    }

    int size_h, size_v;
    float scale;

    Panel->GetSize(&size_h, &size_v );

    if (xmax-xmin > ymax-ymin) scale = size_h/(xmax-xmin);

        else scale = 0.75*(size_v/(ymax-ymin));

    dc.SetPen( wxPen( *wxBLUE));

    scale = scale * 2;

    int polygon_edges, v1, v2, v3;

    v1 = 0;
    v2 = 1;
    v3 = 2;

    for (int i = 0; i < no_polygons;i++)
    {
        meshFile >> polygon_edges >> v1 >> v2 >> v3;

        /*dc.DrawLine( -1.0 *dataPoint[v1][0]*scale+size_h/2,-1.0 *dataPoint[v1][1]*scale+size_v/2, -1.0 *dataPoint[v2][0]*scale+size_h/2, -1.0 *dataPoint[v2][1]*scale+size_v/2 );

        dc.DrawLine( -1.0 *dataPoint[v2][0]*scale+size_h/2,-1.0 *dataPoint[v2][1]*scale+size_v/2, -1.0 *dataPoint[v3][0]*scale+size_h/2, -1.0 *dataPoint[v3][1]*scale+size_v/2 );

        dc.DrawLine( -1.0 *dataPoint[v3][0]*scale+size_h/2,-1.0 *dataPoint[v3][1]*scale+size_v/2, -1.0 *dataPoint[v1][0]*scale+size_h/2, -1.0 *dataPoint[v1][1]*scale+size_v/2 );*/

        dc.DrawLine( dataPoint[v1][0]*scale+size_h/2,dataPoint[v1][1]*scale+size_v/2, dataPoint[v2][0]*scale+size_h/2, dataPoint[v2][1]*scale+size_v/2 );

        dc.DrawLine( dataPoint[v2][0]*scale+size_h/2,dataPoint[v2][1]*scale+size_v/2, dataPoint[v3][0]*scale+size_h/2, dataPoint[v3][1]*scale+size_v/2 );

        dc.DrawLine( dataPoint[v3][0]*scale+size_h/2,dataPoint[v3][1]*scale+size_v/2, dataPoint[v1][0]*scale+size_h/2, dataPoint[v1][1]*scale+size_v/2 );

        std::getline(meshFile, str);

    }

    meshFile.close();
}
