#ifndef FEATURE_H
#define FEATURE_H

#include <G3D/G3DAll.h>
#include <GLG3D/GLG3D.h>
#include "SearchTree.h"
#include "ColorYIQ.h"

/**
 Feature vector stored at each pixel in a source image, A or B.
 Defined in section 3.1 of Image Analogies, described in section
 3.3
 */
class SourceFeature {
public:

    ColorYIQ    color;

    /** x and y spatial 1st derivatives of luminance */
    Vector2     derivative;

    inline static float computeLuminance(const Color3& c) {
        return c.r * 0.299f + c.g * 0.587f + c.b * 0.114f;
    }

    inline SourceFeature() : derivative(0, 0) {
    }

    inline SourceFeature(const Color3& c, const Vector2& d) : 
         color(c), 
         derivative(d) {
    }

    inline SourceFeature(const ColorYIQ& c, const Vector2& d) : 
         color(c), 
         derivative(d) {
    }

    /** Needed for Map2D' bilinear + bicubic */
    inline SourceFeature operator*(float k) const {
        return SourceFeature(color * k, derivative * k);
    }

    /**
     Returns the sum squared of distances between these features. 
     */
    float distanceSquared(const SourceFeature& s, bool luminanceOnly) const;

    /** Needed for Map2D's bilinear + bicubic */
    inline SourceFeature operator+(const SourceFeature& s) const {
        return SourceFeature(color + s.color, derivative + s.derivative);
    }

    /**
       Serializes this source feature to the end of the vector.
       Used by ImageAnalogy::makeFeatureVector.
    */
    void extendFeatureVector(FeatureVector& feature, bool luminanceOnly) const;

};

/**
 Feature vector stored at each pixel of the target image A' or B';
 this may be the same as SourceFeature but does not have to be.
 */
typedef SourceFeature TargetFeature;

typedef Map2D<SourceFeature> SourceImage;
typedef Map2D<TargetFeature> TargetImage;

#endif
