//
// shaping.h
//
// purpose:
//    kind of a "graphic equalizer" for pictures, to allow for different
//    brightness areas to get different amplification.
//
//
// Written by John A deLaubenfels, https://www.adaptune.com/steg.htm .
// Permission granted to use freely in any non-fraudulent way.
//
//
//


#ifndef SHAPING_H
#define SHAPING_H




// forward declarations:
class Shaping;
class ShapingAnch;
class Shap2DAnch;




// qxShaping

class Shaping {

friend  ShapingAnch;

private:
   Shaping         *m_next;
   double          m_myValIn;
   double          m_myValOut;

public:
   Shaping(double dIn=0.0, double dOut=0.0);
   Shaping(const Shaping& rs);   // copy constructor
   ~Shaping();
   const Shaping& operator=(const Shaping&);

   virtual int memoryUnderMySway() const;

   Shaping *next()             {return m_next;}
   const Shaping *next() const {return m_next;}

   double myValIn() const {return m_myValIn;}
   double myValIn(double newVal) {m_myValIn = newVal; return m_myValIn;}

   double myValOut() const {return m_myValOut;}
   double myValOut(double newVal) {m_myValOut = newVal; return m_myValOut;}
};



// qxShapingAnch

class ShapingAnch: public Shaping {
private:
   char *m_shapeName;                 // 05-06-02
   int       m_nBone;                 // 05-07-02
   int       m_sillyLin : 1;          // 10-07-02: silly linear stuff for stick stretching.
   const Shaping **m_shapeBone;       // 05-07-02

public:
   ShapingAnch();
   ShapingAnch(const ShapingAnch& rs);   // copy constructor
   ~ShapingAnch();
   const ShapingAnch& operator=(const ShapingAnch&);

   virtual int memoryUnderMySway() const;

   const char *shapeName() const {return m_shapeName;}
   const char *shapeName(const char *newName);

   int sillyLin() const {return m_sillyLin;}
   int sillyLin(int newVal) {m_sillyLin = newVal; return m_sillyLin;}

   const Shaping **shapeBone() const {return m_shapeBone;}
   int free_bone();
   int make_bone();

   int subCt() const;
   int free_list();
   int read_list(const char *fileName, FILE *fp_inf=NULL);
   int write_list(const char *fileName) const;   // 05-07-02
   int write_list(const char *fileName);         // 05-07-02
   int write_list(FILE *fp_out)         const;   // 05-07-02
   int addPair(double valIn, double valOut);     // 10-07-02
   int linkMe(Shaping *shpAdd);
   int dlinkMe(const Shaping *shpAdd);
   double inToOut(double valIn) const;
   bool bIsInRange(double valIn) const;
   double maxIn() const;                         // 11-16-04
   int getIth(int i, double &dFirstOut, double &dSecondOut) const;
   int transformIn( double factr=1.0, double offst=0.0);
   int transformOut(double factr=1.0, double offst=0.0);
};



// qxxAndAnch

struct xAndAnch {
   double        xVal;
   ShapingAnch   myAnch;
}; // struct xAndAnch





// qxShap2DAnch

class Shap2DAnch {
private:
   std::vector<xAndAnch>     m_vcAnchs;

public:
   double inToOut(double xIn, double yIn) const;
}; // class Shap2DAnch





#endif // ifndef SHAPING_H


