/*=========================================================================

  Program:   Visualization Toolkit
  Module:    grid3D.h
  Language:  C++
  Date:      Date: 08/15/2002 17:00:00 
  Version:   Revision: 1.0 

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen 
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/

//vtk include file
#include "vtkPointPicker.h"
#include "vtkStructuredGrid.h"
#include "vtkUnstructuredGrid.h"
#include "vtkPolyData.h"
#include "vtkCell.h"
#include "vtkCellPicker.h"
#include "vtkTextMapper.h"
#include "vtkFollower.h"
#include "vtkVectorText.h"
#include "vtkTexturedSphereSource.h"
#include "vtkEarthSource.h"
#include "vtkSphereSource.h"
#include "vtkTexture.h"
#include "vtkPNMReader.h"
#include "vtkConeSource.h"
#include "vtkGlyph3D.h"
#include "vtkPolyDataMapper.h"
#include "vtkShrinkFilter.h"
#include "vtkDataSetMapper.h"
#include "vtkCamera.h"
#include "vtkActor.h"
#include "vtkLODActor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"

#ifndef __grid3D_h
#define __grid3D_h

#include <netcdfcpp.h>
#include <string.h>

#define VTK_MAX_SPHERE_RESOLUTION 1024

//extern grid3D *POPgrid;

const long double earthRadius = 6372799.0; // Mean radius in meters
const int earthWindowX = 800;
const int earthWindowY = 800;

class IdToIndex
{
public:
    long I;
    long J;
};

//class VTK_EXPORT grid : public vtkPolyDataSource 
class grid3D : public vtkPolyDataSource 
{
public:
  vtkTypeMacro(grid3D,vtkPolyDataSource);

    // default constructor wer are passing it a resolution to set the theta and 
    // phi resolutions for the sphere on which the earth is mapped.  I am not sure 
    // exactly but I think this value determines how polygonal the sphere becomes.
  grid3D(long res=8);

    //default destructor is empty: no objects to delete
    ~grid3D() {}

    // Both created so compiler does not create machine specific functions
  grid3D(const grid3D&);
  void operator=(const grid3D&);


    /************************ custom funstions ***************************************/

    //only runs once when a grid3D object is instantiated.  This sets up the grid with the
    // given parameters from the g.rds.in file and also e.nc for now. Whil I am here another 
    // poblem is that we shoul be able to read data from different files and not always have to
    // rename them e.nc.  We are workng on this but I am not sure if it will be ready for this release.  
  void Execute();

    // similar to execute. I am not sure exaclty when this is called but 
    // I think it is also automatically called at some point.  
  void ExecuteInformation();

    //
  double SphericalDistance(double lon1, double lat1, double lon2, double lat2);
  long double SphericalAngle(double lon0, double lat0, double lon1, double lat1);

    //float[] GetWorldCoordinates(float Lat, float Long);

  float GetCellElevation(long theCellId)
  {
      return cellElevation[theCellId];
  }

  void SetCellElevation(float theNewElevation, long theCellId)
  {
      cellElevation[theCellId] = theNewElevation;
  }

  void ReadElevationFromFile(char* inp="e.nc",
                             char* dat="elevation",
                             char* lon="ULON",
                             char* lat="ULAT");
  
  void WriteElevationToFile(char* inp="e_input.nc",
                            char* dat="elevation");
  
    void ResetScalarMapper();

    
  
  float GetPointElevation (long theId)
  {
      return pointElevation[theId];
  }

  void SetPointElevation (float theNewElevation, long theId)
  {
      pointElevation[theId] = theNewElevation;
      return;
  }

  NcFile *elevationFile;
  long iNumCells;  // Length of i (X) dimension of all cell arrays
  long jNumCells;  // Length of j (Y) dimension of all cell arrays
                  // In J (N-S) direction only, this is one less than
                  // the number of N-S points.  However, E-W is equal
                  // due to wrap-around.  This small difference can
                  // be confusing, however, so I chose to keep both
                  // pairs as separate data members.
  long iNumPts;
  long jNumPts;

    long totalNumPts;
    long totalNumCells;

  // Given I and J, obtain an Id in the VTK data structure
  long** pointId; // used as ...->pointId[i][j], i=0:iNumCells, j=0:jNumCells+1
  long** cellPointId; // k=0:3, values come from pointId array
  long** cellId;  // i=0:iNumCells, j=0:jNumCells

  // Given the Id, obtain the I and/or J indices of the structured grid
  IdToIndex* pointIndex;
  IdToIndex* cellIndex;

  float* pointTheta;
  float* pointPhi;

  float* cellTheta;
  float* cellPhi;
  float *ULAT, *ULON, *HTN, *HTE, *HUS, *HUW, *ANGLE;

  float maxElevation, minElevation;
  float Radius;
  float Center[3];
  long ThetaResolution;
  long PhiResolution;
  float StartTheta;
  float EndTheta;
  float StartPhi;
  float EndPhi;
  char InputFile[20];

    long OnRatio;
    const long double DegToRad;
  
  private:
    float* pointElevation;  // Indexed by pointId
    float* cellElevation;  // Indexed by cellId
};

#endif

