#define UPLEFT      -1
#define UPCENTER    0
#define UPRIGHT     1
#define TOP         2

// Definitions for weight modifications
#define NOCHANGE    255 
#define REMOVE      0
#define SOLIDIFY    1


// Not defined? Oh well, define it.


struct ByteVec3 { unsigned char r, g, b; };

struct SeamPixel
{
    ~SeamPixel(){ };
    double energy;
    int seam_parent;
};

struct Img
{
    unsigned char *data;
    int w;
    int h;
    int Bpp;

    int ind_col(int i, int j) { return w*j*Bpp + i*Bpp; }
};


class BuffImg
{
public:
    unsigned char *data;
    int *removal_index;
    int w;
    int h;
    int Bpp;

    int ind_col(int i, int j) { return w*j*Bpp + i*Bpp; }
    int ind(int i, int j) { return w*j + i; }
    void init(Img img);
};


class ScratchImg
{
public:
    ~ScratchImg();
    unsigned char *data;
    SeamPixel *spixels;
    int *orig_i;
    unsigned char *weights;

    int w;
    int h;
    int Bpp;

    int ind_col(int i, int j) { return w*j*Bpp + i*Bpp; }
    int ind(int i, int j) { return w*j + i; }

    double compute_energy(int i, int j);
    void compute_forward_e(int i, int j, double* cl, double* cu, double *cr);
    void build_seam(bool use_forward);

};







class SeamImg
{
public:

    void init(Img img);

    void compute_seams(int num_seams, bool use_forward, Img* weights);
    void rebuild_scratch(int seam_num, Img *weights); 
    void save_seam(int seam_num);       // Put seam back into original.

    void build_scaled(int width, Img* scaled);
    void build_scaled_down(int width, Img* scaled);
    void build_scaled_up(int width, Img* scaled);

    void color_orig_seam_red(int seam_num);

    BuffImg buff;
    ScratchImg scratch;
};


Img readpng(const char* filename);

