///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Copyright (C) 2006 by Intel Corporation and Carnegie Mellon University    //
// Contacts: casey.j.helfrich @ intel.com                                    //
//           bdr @ cs.cmu.edu                                                //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#ifndef __FEATUREMAP_HXX
#define __FEATUREMAP_HXX

#include <list>
#include <vector>

#include "GlobalConstants.hxx"
#include "Primitives.hxx"

class Feature;

#include "Network.hxx"

////////////////////////////////////////////////////////////////////////////// 
// NOTE: featureID of 0 is NOT a valid feature. Features are numbered 
// [1,NUM_FEATURES].  
//

////////////////////////////////////////////////////////////////////////////// 
// Feature : describes a point on the surface of a Catom with a specific 
//           location and networkadapter
//

class Feature
{
private:
  
  catomID hostCatomID;
  featureID FID;
  
  
  // Networking support
  NetworkAdapter NA;

  // support for multiple remote features in contact
  vector<Feature*> remote_features;
  
public:
  // locations relative to center of catom
  static Point3D *locations;
  // faces corresponding to features for faceted catoms
  static vector<Point3D> *faces;
  
  // Accessor Methods
  featureID getFID() { return FID; }
  catomID getHostcatomID() { return hostCatomID;  }
  Point3D getLocation() { return locations[FID]; }
  NetworkAdapter* getNetworkAdapter() { return &NA; }
  
  // Query the simulator and find the feature on another catom
  // that this feature is touching
  Feature* getNthRemoteFeature( unsigned int i ) {
    if (i<remote_features.size()) return remote_features[i];
    return 0;
  };
  unsigned int getNumRemoteFeatures() { return remote_features.size(); };

  // The following returns 0th remote feature, if any
  // deprecated, but kept for compatibility
  Feature* getRemoteFeature() { return getNthRemoteFeature( 0 ); };

  // Should not be used by catom programmers -- used by physics engine
  void addRemoteFeature( Feature* f ) { 
    unsigned int i;
    for (i=0; i<remote_features.size(); i++) 
      if (remote_features[i]==f) return;
    remote_features.push_back( f );
  };
  void clearRemoteFeatures() { remote_features.clear(); };
  
//  // Constructor: Feature(hostCatomID, FID, location);
//  Feature(catomID, featureID, Point3D);
  // Constructor: Feature(hostCatomID, FID);
  Feature(catomID, featureID);

  // creates an invalid feature!  Required for FeatureMap Constructor
  Feature() : NA(0,0) {} 

  // Deconstructor
  ~Feature();
};

void get_lattice_info( string name, unsigned int *lattice_type, unsigned int *num_features, unsigned int *num_neighbors );
void get_feature_map( unsigned int lattice_type, catomID i, Feature *map );

#endif    /* __FEATUREMAP_H */
