#include "summalgorithmcore.h"


/*===== Interfaces =====*/
SummAlgorithmCore::SummAlgorithmCore(int id)
{
    setId(id);
}

int SummAlgorithmCore::getId() const
{
    return id;
}

void SummAlgorithmCore::setId(int id)
{
    this->id = id;
}


/*===== FixedLengthIntervalLmAlgorithm =====*/
FixedLengthIntervalLmAlgorithmParams::FixedLengthIntervalLmAlgorithmParams() : SummAlgorithmParams()
{
    segmentLength = 50;
    segmentCount = 10;
    featureRowIndex = 33;
}

SummAlgorithmParams *FixedLengthIntervalLmAlgorithmParams::clone() const
{
    FixedLengthIntervalLmAlgorithmParams *newParams = new FixedLengthIntervalLmAlgorithmParams;
    newParams->segmentLength = this->segmentLength;
    newParams->segmentCount = this->segmentCount;
    newParams->featureRowIndex = this->featureRowIndex;

    return newParams;
}

FixedLengthIntervalLmAlgorithmCore::FixedLengthIntervalLmAlgorithmCore() : SummAlgorithmCore()
{
    this->params = (FixedLengthIntervalLmAlgorithmParams *)createDefaultParams();
}

void FixedLengthIntervalLmAlgorithmCore::setParams(SummAlgorithmParams *params)
{
    delete this->params;
    this->params = (FixedLengthIntervalLmAlgorithmParams *)params;
}

SummAlgorithmParams *FixedLengthIntervalLmAlgorithmCore::getParams() const
{
    return params;
}

SummAlgorithmParams *FixedLengthIntervalLmAlgorithmCore::createDefaultParams() const
{
    return new FixedLengthIntervalLmAlgorithmParams();
}

SummAlgorithmCore *FixedLengthIntervalLmAlgorithmCore::clone() const
{
    FixedLengthIntervalLmAlgorithmCore *newCore = new FixedLengthIntervalLmAlgorithmCore();
    newCore->setParams(this->params->clone());
    newCore->setId(this->getId());

    return newCore;
}

SummarizationFramework::Model::TubeCollectionPtr FixedLengthIntervalLmAlgorithmCore::process(cv::Mat & data, QString filename)
{
    assert(params != NULL);
    assert(params->segmentCount > 0);
    assert(params->segmentLength > 0);
    assert(params->featureRowIndex < data.rows);

    SummarizationFramework::TubeFeatures::Features::ITubeFeature::FeatureData featureRoi = data.row(params->featureRowIndex);

    SummarizationFramework::Model::VideoSequencePtr videoSequence = new SummarizationFramework::Model::VideoSequence(filename.toStdString());
    SummarizationFramework::Model::TubePtr videoTube = new SummarizationFramework::Model::Tube(NULL, SummarizationFramework::FrameSpan(1, videoSequence->GetLength()), filename.toStdString());

    SummarizationFramework::TubeFeatures::Segmentation::FixedLengthIntervalLmFeatureSegmentator segmentator(params->segmentLength);
    segmentator.SetMaxSegmentsCount(params->segmentCount);
    segmentator.SetIntervalMerging(true, params->segmentLength/2 - 1);

    SummarizationFramework::Model::TubeCollectionPtr tubes = segmentator.SegmentTubes(featureRoi, videoTube);
    tubes->Sort(new SummarizationFramework::Model::TubeCollection::ByOriginalStartSortPredicate());

    return tubes;
}


/*===== CoverageDrivenLmFeatureSegmentator =====*/
CoverageDrivenLmAlgorithmParams::CoverageDrivenLmAlgorithmParams() : SummAlgorithmParams()
{
    segmentLength = 50;
    segmentCount = 10;
    featureRowIndex = 33;
}

SummAlgorithmParams *CoverageDrivenLmAlgorithmParams::clone() const
{
    CoverageDrivenLmAlgorithmParams *newParams = new CoverageDrivenLmAlgorithmParams;
    newParams->segmentLength = this->segmentLength;
    newParams->segmentCount = this->segmentCount;
    newParams->featureRowIndex = this->featureRowIndex;

    return newParams;
}

CoverageDrivenLmAlgorithmCore::CoverageDrivenLmAlgorithmCore() : SummAlgorithmCore()
{
    this->params = (CoverageDrivenLmAlgorithmParams *)createDefaultParams();
}

void CoverageDrivenLmAlgorithmCore::setParams(SummAlgorithmParams *params)
{
    delete this->params;
    this->params = (CoverageDrivenLmAlgorithmParams *)params;
}

SummAlgorithmParams *CoverageDrivenLmAlgorithmCore::getParams() const
{
    return params;
}

SummAlgorithmParams *CoverageDrivenLmAlgorithmCore::createDefaultParams() const
{
    return new CoverageDrivenLmAlgorithmParams();
}

SummAlgorithmCore *CoverageDrivenLmAlgorithmCore::clone() const
{
    CoverageDrivenLmAlgorithmCore *newCore = new CoverageDrivenLmAlgorithmCore();
    newCore->setParams(this->params->clone());
    newCore->setId(this->getId());

    return newCore;
}

SummarizationFramework::Model::TubeCollectionPtr CoverageDrivenLmAlgorithmCore::process(cv::Mat & data, QString filename)
{
    assert(params != NULL);
    assert(params->segmentCount > 0);
    assert(params->segmentLength > 0);
    assert(params->featureRowIndex < data.rows);

    SummarizationFramework::TubeFeatures::Features::ITubeFeature::FeatureData featureRoi = data.row(params->featureRowIndex);

    SummarizationFramework::Model::VideoSequencePtr videoSequence = new SummarizationFramework::Model::VideoSequence(filename.toStdString());
    SummarizationFramework::Model::TubePtr videoTube = new SummarizationFramework::Model::Tube(NULL, SummarizationFramework::FrameSpan(1, videoSequence->GetLength()), filename.toStdString());

    SummarizationFramework::TubeFeatures::Segmentation::CoverageDrivenLmFeatureSegmentator segmentator(params->segmentLength);
    segmentator.SetMaxSegmentsCount(params->segmentCount);
    segmentator.SetIntervalMerging(true, params->segmentLength/2 - 1);

    SummarizationFramework::Model::TubeCollectionPtr tubes = segmentator.SegmentTubes(featureRoi, videoTube);
    tubes->Sort(new SummarizationFramework::Model::TubeCollection::ByOriginalStartSortPredicate());

    return tubes;
}
