// channels.h
#ifndef CHANNELS_H
#define CHANNELS_H

#include <cassert>
#include <cmath>
#include "balance.h"

#define LINK_DHSVM

#ifdef LINK_DHSVM
#include "channel.h"
#endif

using namespace std;

#ifdef LINK_DHSVM
// Interface function for C code 
//extern "C" {
//static int
//channel_route_segment(Channel *segment, int deltat);
//}
#endif

// Abastract Base class for Channel w/ hydraulic routing ------------------------------------
class ChannelWater : public WaterBalance
{
public:
  ChannelWater(){ ; }
  ChannelWater( float startDepth, float length, float slope, float roughness );
  void channelStateWater( float startDepth, float length, float slope, float roughness );
  float waterDepth() { return d_waterDepth; }
  float calcDerivative( float dummy, float depth );     // calculate the derivative for solving ODE
  float solveBalance( float inVol, float startDepth, float endDepth );
  void getInflux( float inFlux ) { ds_inFlux = inFlux; }

  virtual inline float surfaceArea( float depth ) = 0;    // surface area (m^2)
  virtual inline float crossSecArea( float depth ) = 0;   // cross-sectional area (m^2)
  virtual inline float hydRadius( float depth ) = 0;      // hydraulic radius (m)
  virtual inline float storageVol( float depth ) = 0;      // volume of water in channel (m)
  
protected:
  float d_waterDepth;                                  // average depth of water in the channel (m)
  float d_length;                                      // channel length (m)
  float d_slope;                                       // slope (m/m) - stored as sqrt(slope)
  float d_roughness;                                     // Manning's roughness
  static float ds_inFlux;
};

// Final RectangularChannel Class -----------------------------------------------------------
class RectangularChannelWater : public ChannelWater
{
public:
  RectangularChannelWater(){ ;}
  RectangularChannelWater( float startDepth, float width, float length, float slope, float roughness );
  void initialStateWater( float startDepth, float width, float length, float slope, float roughness );

  inline float surfaceArea( float depth );
  inline float crossSecArea( float depth );
  inline float hydRadius(float depth );
  inline float storageVol( float depth );
protected:
  float d_bottomWidth;
};

#endif

