////////////////////////////////////////////////////////////////////////
//
// SecWeight.h - contains a set of classes using different weighting
//               functions for given secondary structures
//
// $Id: SecWeight.h,v 1.5 2001/12/28 18:27:15 goetz Exp $
//
////////////////////////////////////////////////////////////////////////

#ifndef SECWEIGHT_H
#define SECWEIGHT_H

#include "Alignment.h"

//////////////////////////////////////////////////////////////////////
// abstract base class
class SecWeight
{
public:
  /** this function gives the distance weight of two chars */
  virtual double w(const Alchar &a) const =0;
  
  SecWeight(const string &name)
    : name(name)
  {};
  
  /** returns description of scoring matrix */
  operator const string() const
  { return name; }

  /** destructor */
  virtual ~SecWeight() {};
private:
  string name;
};

//////////////////////////////////////////////////////////////////////
// default class: all factors are 1
class DefaultSecW : public SecWeight
{
public:
  virtual double w(const Alchar &a) const;

  DefaultSecW () 
    : SecWeight("DefaultSecW") 
  {}
};

//////////////////////////////////////////////////////////////////////
// the following classes are a set of weighting functions
// they can be used with the appropiate SecWeight subclasses
// they are type independant, ie. they do not care about the
// Alchar "a" Secondary structure type information and may 
// produce strange results if applied to regions without secondary
// structure

// base class - no implementation
class SecWeightFunc
{
public:
  virtual double w(const Alchar &a) const =0;

  SecWeightFunc()
  {}

  virtual ~SecWeightFunc() {}
};

// block scale with fixed offset:
// function has value "scale" within interval [beg+"offset", end-"offset"]
// and value 1 otherwise, where beg and end are begin and end positions of
// secondary structure
class BlockScaleFixed : public SecWeightFunc
{
public:
  virtual double w(const Alchar &a) const;
  
  BlockScaleFixed( double scale, unsigned int offset= 0)
    : scale(scale), offset(offset)
  {}

private:
  double scale;
  unsigned int offset;
};

// block scale with proportional offset:
// function has value "scale" in interval [beg+len*"offset", end-len*"offset"]
// and value 1 otherwise, where beg and end are begin and end positions of
// secondary structure and len=end-beg is the length of the structure
class BlockScaleProp : public SecWeightFunc
{
public:
  virtual double w(const Alchar &a) const;
  
  BlockScaleProp( double scale, double offset= 0)
    : scale(scale), offset(offset)
  {}

private:
  double scale;
  double offset;
};

// piecewise linear function with proportional offset:
// function has value "scale" in interval [beg+"offset", end-"offset"]
// and value 1 outside interval [beg, end]. Between these intervals the
// function is continuous and linear.
// beg and end are begin and end positions of
// secondary structure and len=end-beg is the length of the structure
class LinearFixed : public SecWeightFunc
{
public:
  virtual double w(const Alchar &a) const;

  LinearFixed( double scale, unsigned int offset= 0)
    : scale(scale), offset(offset)
  {}

private:
  double scale;
  unsigned int offset;
};

// piecewise linear function with proportional offset:
// function has value "scale" in interval [beg+"offset", end-"offset"]
// and value 1 outside interval [beg, end]. Between these intervals the
// function is continuous and linear.
// beg and end are begin and end positions of
// secondary structure and len=end-beg is the length of the structure
class LinearProp : public SecWeightFunc
{
public:
  virtual double w(const Alchar &a) const;

  LinearProp( double scale, double offset= 0)
    : scale(scale), offset(offset)
  {}

private:
  double scale;
  double offset;
};

// class for using two of the above independant functions for alpha
// helix and beta strand secondary structure. For each structure type
// a funtion must be given and the value returned is the one of the 
// matching structure type
class IndepSecW : public SecWeight
{
public:
  virtual double w(const Alchar &a) const;
  
  IndepSecW (const SecWeightFunc *falpha, const SecWeightFunc *fbeta) 
    : SecWeight("IndepFunc"), falpha(falpha), fbeta(fbeta)
  {}
  
private:
  const SecWeightFunc *falpha;
  const SecWeightFunc *fbeta;
};

#endif
