// Using a list to sort grid cells by elevation and return row-col
//
// call from InitTerrain()
// 
// need to define the external call, so after header file listing declare:
//
// extern void sortElev( int numCells, float *elev, int **row_col );
//
// then in the subroutine just call c-interface as:
//
//  sortElev( numCells, elev, row_col );
// 
// where elev is the vector of elevations and row_col is a 2-D array with
// corresponding row and col numbers,  See test_sort.c for example.

#include "sortelev.h"

//#define TEST

// for use in DHSVM
extern "C" {
  void sortElev( int numCells, float *elev, int **row_col );
}

//----------------------------------------------------------------------------
//   PUBLIC FUNCTIONS
//----------------------------------------------------------------------------
Index::Index( float elev, int row, int col ){
    d_elev = elev;
    d_row = row;
    d_col = col;
}

inline float Index::elev(){ return d_elev; }
inline int Index::row(){ return d_row; }
inline int Index::col(){ return d_col; }

// sort by elevation
inline bool Index::operator==(const Index &a) const{
  return d_elev == a.d_elev;
}

inline bool Index::operator<(const Index &a) const{
  return d_elev < a.d_elev;
}
// end Index class functions -------------------------


// display list for testing
void display( list<Index> &lst ){
  list<Index>::iterator p;

  for( p=lst.begin(); p!=lst.end(); p++ ){
    cout << "elev: " << p->elev();
    cout << "  row: " << p->row();
    cout << "  col: " << p->col();
    cout << endl;
  }
  cout << endl;
}

// c interface function to sort by elevation
void sortElev( int numCells, float *elev, int **row_col ){
  int i;
  list<Index> lst;

  // load in list for sorting
  for( i = 0; i < numCells; i++ ){
    lst.push_back( Index( elev[i],  row_col[i][0], row_col[i][1]) );
  }

  lst.sort();   // sort it!

  // map back sorted list
  i = 0;
  list<Index>::iterator p;
  for( p=lst.begin(); p!=lst.end(); p++ ){
    row_col[i][0] = p->row();
    row_col[i][1] = p->col();
    i++;
  }
}


#ifdef TEST
//----------------------------------------------------------------------------
//   TEST CODE
//----------------------------------------------------------------------------
int main(){
  list<Index> lst;

  lst.push_back( Index( 80,  0, 4) );
  lst.push_back( Index( 90,  1, 3) );
  lst.push_back( Index( 100, 2, 2) );
  lst.push_back( Index( 70,  3, 1) );
  lst.push_back( Index( 50,  4, 0) );

  // display unsorted list
  display( lst );

  // sort by elevation
  lst.sort();

  // display sorted list
  display( lst );

  return 0;
}

#endif
