#include "Img.h"
#include "knn_img.h"

#include <cstdio>
#include <cstdlib>

struct PixCand
{
    int i, j;
    double weight;
};

struct PixPtr
{
    int i, j;
};

class ExempPtr
{
public:
    ExempPtr() { }
    
    void init(Img *exemp, Img* synth)
    {
        w = synth->get_w();
        h = synth->get_h();

        ptrs = new PixPtr[w*h];
        for(int i = 0; i < w*h; ++i)
        {
            ptrs[i].i = -1;
            ptrs[i].j = -1;
        }
    }

    PixPtr get_ptr(int i, int j) 
    { 
        assert(i >= 0 && i < w);
        assert(j >= 0 && j < h);
        return ptrs[ind(i,j)]; 
    }
    void set_ptr(int i, int j, PixPtr ptr) 
    { 
        assert(i >= 0 && i < w);
        assert(j >= 0 && j < h);
        ptrs[ind(i,j)].i = ptr.i;
        ptrs[ind(i,j)].j = ptr.j;
    }

private:
    int w, h;
    int ind(int i, int j) { return w*j + i; }
    PixPtr* ptrs;

};




class SynthImg
{
public:
    SynthImg();

    //ws, hs = synth size.
    void init(Img* img, int ws, int hs, const char* file, int rad);

    bool in_bounds_synth(int i, int j);
    bool in_shared_bounds(int i_off, int j_off, int i_exemp, int j_exemp,
                                                int i_synth, int j_synth );

    void synthesize();

    void copy_pix_exemp_synth(int i_exemp, int j_exemp,int i_synth,int j_synth);

    PixCand normalized_of_best_nn(int x, int y, int i, int j);
    double compute_normalized_weight(int i_exemp, int j_exemp,
                                        int i_synth, int j_synth);


    void print_synth_ppm();

    void print_nns(int d);



private:
    Img exemplar;
    Img synth;
    ExempPtr ptrs;

    KNN nns;

    int nradius;
};

