#include "WimaTrackerPolyline.h"

WimaTrackerPolyline::WimaTrackerPolyline(QObject *parent)
    : WimaTrackerPolyline (nullptr, parent)
{
}

WimaTrackerPolyline::WimaTrackerPolyline(QGCMapPolyline *other, QObject *parent)
    :QGCMapPolyline (other, parent)
    , _boundArea  (nullptr)
    , _startVertexIndex(0)
    , _endVertexIndex(0)
{
}

void WimaTrackerPolyline::bindPolygon(WimaArea *polygon)
{
    if(polygon != nullptr){
        _boundArea = polygon;
        connect(polygon, &WimaArea::pathChanged, this, &WimaTrackerPolyline::recalcPolyline);
    }else{
        qWarning("bindPolygon(): Invalid Object!");
    }
}

void WimaTrackerPolyline::unbindPolygon()
{
    if(_boundArea != nullptr){
        disconnect(_boundArea, &WimaArea::pathChanged, this, &WimaTrackerPolyline::recalcPolyline);
        _boundArea = nullptr;
    }else{
        qWarning("unbindPolygon(): No Object bound!");
    }
}

void WimaTrackerPolyline::swapEndPoints()
{
    int storage         = _startVertexIndex;
    _startVertexIndex   = _endVertexIndex;
    _endVertexIndex     = storage;
    recalcPolyline();
}


void WimaTrackerPolyline::setStartVertexIndex(int PolygonVertexIndex)
{
    if(PolygonVertexIndex >= 0 && PolygonVertexIndex < _boundArea->count()){
        _startVertexIndex = PolygonVertexIndex;
        emit startVertexIndexChanged();
        recalcPolyline();
    }else{
        qWarning("WimaTrackerPolyline::setStartVertexIndex(): Index out of bounds!");
    }
}

void WimaTrackerPolyline::setEndVertexIndex(int PolygonVertexIndex)
{
    if(PolygonVertexIndex >= 0 && PolygonVertexIndex < _boundArea->count()){
        _endVertexIndex = PolygonVertexIndex;
        emit endVertexIndexChanged();
        recalcPolyline();
    }else{
        qWarning("WimaTrackerPolyline::setEndVertexIndex(): Index out of bounds!");
    }
}

void WimaTrackerPolyline::snapVertex(int polylineVertexIndex)
{
    int polylineVertexCount = this->count();
    if (polylineVertexIndex >= 0 && polylineVertexIndex < polylineVertexCount){
        if (polylineVertexIndex == 0){
            snapStartVertex();
        }else if (polylineVertexIndex == polylineVertexCount-1) {
            snapEndVertex();
        }else {
            int polygonVertexIndex = _startVertexIndex + polylineVertexIndex;
            int polygonVertexCount = _boundArea->count();
            if (polygonVertexIndex >= polygonVertexCount){
                polygonVertexIndex = polygonVertexIndex - polygonVertexCount;
                if (polygonVertexCount > _endVertexIndex) {
                    // This branch sould actually not be reachable, just in case...
                    qWarning("WimaTrackerPolyline::snapVertex(): polylineVertexIndex out of bounds!");
                    return;
                }
            }
            this->adjustVertex(polylineVertexIndex, _boundArea->vertexCoordinate(polygonVertexIndex));
        }
    }else {
        qWarning("WimaTrackerPolyline::snapVertex(): Index out of bounds!");
    }
}

void WimaTrackerPolyline::snapEndVertex()
{
    if (_boundArea != nullptr && _boundArea->count() >= 3){
        int currentVertexIndex = this->count()-1;
        int closestVertexIndex          = _boundArea->getClosestVertexIndex(this->vertexCoordinate(currentVertexIndex));
        QGeoCoordinate closestVertex    = _boundArea->vertexCoordinate(closestVertexIndex);
        _endVertexIndex                 = closestVertexIndex;
        this->adjustVertex(currentVertexIndex, closestVertex);
        this->recalcPolyline();
    }
}

void WimaTrackerPolyline::snapStartVertex()
{
    if (_boundArea != nullptr && _boundArea->count() >= 3){
        int currentVertexIndex = 0;
        int closestVertexIndex          = _boundArea->getClosestVertexIndex(this->vertexCoordinate(currentVertexIndex));
        QGeoCoordinate closestVertex    = _boundArea->vertexCoordinate(closestVertexIndex);
        _startVertexIndex               = closestVertexIndex;
        this->adjustVertex(currentVertexIndex, closestVertex);
        this->recalcPolyline();
    }
}

void WimaTrackerPolyline::recalcPolyline()
{
    //qWarning("WimaTrackerPolyline::recalcPolyline()");
    if (_boundArea != nullptr && _boundArea->count() > 0){
        if (_startVertexIndex >= _boundArea->count()){
            _startVertexIndex = 0;
        }
        if (_endVertexIndex >= _boundArea->count()){
            _endVertexIndex = _boundArea->count()-1;
        }

        this->clear();
        int i = _startVertexIndex;
        while(1){
            this->appendVertex(_boundArea->vertexCoordinate(i));
            if (i == _boundArea->count()-1 && i != _endVertexIndex){
                i = 0;
            }else if (i == _endVertexIndex) {
                break;
            }else {
                i++;
            }

        }
    }else{
        qWarning("WimaTrackerPolyline::recalcPolyline(): No object bound!");
    }
}


