/* 
 * File:   Region.cpp
 * Author: carlos
 * 
 * Created on 6 de noviembre de 2012, 14:55
 */

#include <vector>

#include "ImgRegion.h"
#include <stdio.h>

ImgRegion::ImgRegion() {
    m_label = string("");
    m_points.clear();
}

ImgRegion::ImgRegion(const ImgRegion& orig) {
    this->m_label = orig.m_label;
    this->m_points = orig.m_points;
}

ImgRegion::~ImgRegion() {
}

ImgRegion::ImgRegion(string label){
    m_label = label;
    m_points.clear();
}

int ImgRegion::nearestPointIndex(int xCur, int yCur){
    int nearestIdx = -1;
    double minDist = 99999;

    for(int i=0; i<m_points.size(); i++){
        double dist = euclideanDistance(xCur,yCur,m_points.at(i).GetX(),m_points.at(i).GetY());
        if (dist < minDist){
            minDist = dist;
            nearestIdx = i;
        }
    }
    return nearestIdx;
}

int ImgRegion::printPoints(){
    for (int i=0; i<m_points.size(); i++){
        Pt_t p = m_points.at(i);
        printf("[%d , %d]",m_points.at(i).GetX(),m_points.at(i).GetY());
    }
    printf("\n");
    return 0;
}

int ImgRegion::clearPoints(){
    m_points.clear();
    return 0;
}

int ImgRegion::addPoint(int x, int y){
    Pt_t aux;
    aux.SetX(x);
    aux.SetY(y);
    m_points.push_back(aux);
//    this->printPoints();
    return 0;
}

Pt_t ImgRegion::getPoint(int i){
    return m_points.at(i);
}

int ImgRegion::setPoint(int i, Pt_t value){
    m_points.at(i) = value;    
    return 0;
}

int ImgRegion::getNumPoints(){
    return m_points.size();
}

int ImgRegion::getMaxX(){
    int max = -1;
    
    for(int i=0; i<this->m_points.size(); i++){
        if(m_points.at(i).GetX() > max)
            max = m_points.at(i).GetX();
    }
    
    return max;
}

int ImgRegion::getMaxY(){
    int max = -1;
    
    for(int i=0; i<this->m_points.size(); i++){
        if(m_points.at(i).GetY() > max)
            max = m_points.at(i).GetY();
    }
    
    return max;
}

int ImgRegion::getMinX(){
    int min = 999999;
    
    for(int i=0; i<this->m_points.size(); i++){
        if(m_points.at(i).GetX() < min)
            min = m_points.at(i).GetX();
    }
    
    return min;
}

int ImgRegion::getMinY(){
    int min = 999999;
    
    for(int i=0; i<this->m_points.size(); i++){
        if(m_points.at(i).GetY() < min)
            min = m_points.at(i).GetY();
    }
    
    return min;
}

bool ImgRegion::pointInPolygon(int u, int v){

    int j = m_points.size()-1 ;
    bool oddNodes = false;

    for (int i=0; i<m_points.size(); i++) {
        if ((m_points.at(i).GetY() < v && m_points.at(j).GetY() >= v || 
             m_points.at(j).GetY() < v && m_points.at(i).GetY() >= v)
            &&  (m_points.at(i).GetX() <= u || m_points.at(j).GetX() <= u)) {
            oddNodes^=(m_points.at(i).GetX() + (v-m_points.at(i).GetY())/(m_points.at(j).GetY()-m_points.at(i).GetY())*(m_points.at(j).GetX()-m_points.at(i).GetX())<u); 
        }
        j=i; 
    }

    return oddNodes; 
}
