/*
 * File         : blob.h
 * Author       : Timothy Wiley
 * Version      :
 * Created      : 18/02/2010
 * Description  :
 * Copyright    :
 */

#ifndef THERMAL_BLOBBER_BLOB_H_
#define THERMAL_BLOBBER_BLOB_H_

#include <ros/ros.h>

#include <crosbot/data.hpp>
#include <crosbot/handle.hpp>
#include <crosbot/geometry.hpp>

#include "thermal_blobber/BlobMsg.h"

// Value in thermalImg is spot is below the threshold
#define BELOW_THRESHOLD     0
#define NO_CALC_DISTANCE    -1

#define BLOB_ENCODE_VAL 250

using namespace crosbot;

namespace casualty {

class Blob : public HandledObject {
public:
    // Blob id number
	int id;

	// Blob dimensions
    int minx, miny;
    int maxx, maxy;

    // Centre pixel of the blob's bounding box.
    // This needs to be calculated before use, whenever min/max x/y is changed.
    crosbot::Point2D centre;

    // Blob position
    double averageDistance;
    Point3D p;

    inline Blob(int id, int minx, int miny, int maxx, int maxy):
        id(id),
        minx(minx),
        miny(miny),
        maxx(maxx),
        maxy(maxy)
        {
    	setCentre();
        };
    inline Blob(Blob& other) :
        id(other.id),
		minx(other.minx),
        miny(other.miny),
        maxx(other.maxx),
        maxy(other.maxy),
        centre(other.centre),
        averageDistance(other.averageDistance),
        p(other.p)
        {};
    inline Blob(thermal_blobber::BlobMsg& msgBlob):
		id(msgBlob.id),
		minx(msgBlob.minx),
		miny(msgBlob.miny),
		maxx(msgBlob.maxx),
		maxy(msgBlob.maxy),
		averageDistance(msgBlob.averageDistance),
		p(msgBlob.p)
		{
		setCentre();
		};
    inline ~Blob() {};

    inline int encodeId() {
    	return BLOB_ENCODE_VAL - id;
    }

    static int encodeId(int id) {
    	return BLOB_ENCODE_VAL - id;
    }

    static int decodeId(int encodedId) {
    	return BLOB_ENCODE_VAL - encodedId;
    }

    /**
     * Area of blob
     */
    inline int area() {
        return width() * height();
    };

    /**
     * Height of blob
     */
    inline int height() {
        return maxy-miny;
    };

    /**
     * Width of blob
     */
    inline int width() {
        return maxx-minx;
    };

    /**
     * Sets the centre pixel of the blob
     */
    inline void setCentre() {
        centre = Point2D((maxx+minx)/2, (maxy+miny)/2);
    };

    inline thermal_blobber::BlobMsg toBlobMsg() {
    	thermal_blobber::BlobMsg blob;
    	blob.id = id;
    	blob.minx = minx;
    	blob.miny = miny;
    	blob.maxx = maxx;
    	blob.maxy = maxy;
    	blob.averageDistance = averageDistance;
    	blob.p = p.toROS();
    	return blob;
    }
};
typedef Handle<Blob> BlobPtr;

} // namespace casualty

#endif /* THERMAL_BLOBBER_BLOB_H_ */
