#ifndef _LWENVELOPE_H_
#define _LWENVELOPE_H_

#include "lwo.h"

#include <iostream>

class lwKey
{
public:
    lwKey(float ntime, float nvalue) : time(ntime), value(nvalue) {}
    float          time;
    float          value;
    unsigned int   shape;               /* ID_TCB, ID_BEZ2, etc. */
    float          tension;
    float          continuity;
    float          bias;
    float          param[ 4 ];
};

typedef vector<lwKey*> vkeys;

inline bool operator < (const lwKey &k1, const lwKey &k2)
{
    return k1.time < k2.time;
}

#define BEH_RESET      0
#define BEH_CONSTANT   1
#define BEH_REPEAT     2
#define BEH_OSCILLATE  3
#define BEH_OFFSET     4
#define BEH_LINEAR     5

class lwEnvelope
{
    float range( float v, float lo, float hi, int *i );
    void hermite( float t, float *h1, float *h2, float *h3, float *h4 );
    float bezier( float x0, float x1, float x2, float x3, float t );
    float bez2_time( float x0, float x1, float x2, float x3, float time, float *t0, float *t1 );
    float bez2( lwKey *key0, lwKey *key1, float time );
    float outgoing( unsigned int key0, unsigned int key1 );
    float incoming( unsigned int key0, unsigned int key1 );
    
public:
    lwEnvelope()
    {
        name = 0;
    }

    ~lwEnvelope()
    {
        if (name) free(name);
        unsigned int i;
        for (i=0; i<keys.size(); delete keys[i++]);
        for (i=0; i<cfilters.size(); delete cfilters[i++]);
    }
    
    float evaluate( float time );
    lwKey *addKey( float time, float value );

    int       index;
    int       type;
    char     *name;
    vkeys     keys;                /* linked list of keys */
    int       behavior[ 2 ];       /* pre and post (extrapolation) */
    vplugins  cfilters;            /* linked list of channel filters */
    int       ncfilters;
};

typedef vector<lwEnvelope*> venvelopes;

#endif // _LWENVELOPE_H_

