/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

///////////////////////////////////////////////////
// Mosaic.pp
// S.O. # :
// Author(s): zkira
// $Id: Mosaic.cpp,v 1.20 2011/06/24 04:22:14 mbansal Exp $

#include <stdio.h>
#include <string.h>

#include "Mosaic.h"
#include "trsMatrix.h"

#include "Log.h"
#define LOG_TAG "MOSAIC"

Mosaic::Mosaic()
{
    initialized = false;
    imageMosaicYVU = NULL;
    frames_size = 0;
    max_frames = 200;
}

Mosaic::~Mosaic()
{
    for (int i = 0; i < frames_size; i++)
    {
        if (frames[i])
            delete frames[i];
    }
    delete frames;
    delete rframes;

    if (aligner != NULL)
        delete aligner;
    if (blender != NULL)
        delete blender;
}

int Mosaic::initialize(int blendingType, int stripType, int width, int height, int nframes, bool quarter_res, float thresh_still)
{
    this->blendingType = blendingType;

    // TODO: Review this logic if enabling FULL or PAN mode
    if (blendingType == Blend::BLEND_TYPE_FULL ||
            blendingType == Blend::BLEND_TYPE_PAN)
    {
        stripType = Blend::STRIP_TYPE_THIN;
    }

    this->stripType = stripType;
    this->width = width;
    this->height = height;


    mosaicWidth = mosaicHeight = 0;
    imageMosaicYVU = NULL;

    frames = new MosaicFrame *[max_frames];
    rframes = new MosaicFrame *[max_frames];

    if(nframes>-1)
    {
        for(int i=0; i<nframes; i++)
        {
            frames[i] = new MosaicFrame(this->width,this->height,false); // Do no allocate memory for YUV data
        }
    }
    else
    {
        for(int i=0; i<max_frames; i++)
        {
            frames[i] = NULL;
        }


    }

    LOGV("Initialize %d %d", width, height);
    LOGV("Frame width %d,%d", width, height);
    LOGV("Max num frames %d", max_frames);

    aligner = new Align();
    aligner->initialize(width, height,quarter_res,thresh_still);

    if (blendingType == Blend::BLEND_TYPE_FULL ||
            blendingType == Blend::BLEND_TYPE_PAN ||
            blendingType == Blend::BLEND_TYPE_CYLPAN ||
            blendingType == Blend::BLEND_TYPE_HORZ) {
        blender = new Blend();
        blender->initialize(blendingType, stripType, width, height);
    } else {
        blender = NULL;
        LOGE("Error: Unknown blending type %d",blendingType);
        return MOSAIC_RET_ERROR;
    }

    initialized = true;

    return MOSAIC_RET_OK;
}

int Mosaic::addFrameRGB(ImageType imageRGB)
{
    ImageType imageYVU;
    // Convert to YVU24 which is used by blending
    imageYVU = ImageUtils::allocateImage(this->width, this->height, ImageUtils::IMAGE_TYPE_NUM_CHANNELS);
    ImageUtils::rgb2yvu(imageYVU, imageRGB, width, height);

    return addFrame(imageYVU);
}

int Mosaic::addFrame(ImageType imageYVU)
{
    if(frames[frames_size]==NULL)
        frames[frames_size] = new MosaicFrame(this->width,this->height,false);

    MosaicFrame *frame = frames[frames_size];

    frame->image = imageYVU;

    // Add frame to aligner
    int ret = MOSAIC_RET_ERROR;
    if (aligner != NULL)
    {
        // Note aligner takes in RGB images
        int align_flag = Align::ALIGN_RET_OK;
        align_flag = aligner->addFrame(frame->image);
        aligner->getLastTRS(frame->trs);

        if (frames_size >= max_frames)
        {
            LOGV("WARNING: More frames than preallocated, ignoring."
                 "Increase maximum number of frames (-f <max_frames>) to avoid this");
            return MOSAIC_RET_ERROR;
        }

        switch (align_flag)
        {
            case Align::ALIGN_RET_OK:
                frames_size++;
                ret = MOSAIC_RET_OK;
                break;
            case Align::ALIGN_RET_FEW_INLIERS:
                frames_size++;
                ret = MOSAIC_RET_FEW_INLIERS;
                break;
            case Align::ALIGN_RET_LOW_TEXTURE:
                ret = MOSAIC_RET_LOW_TEXTURE;
                break;
            case Align::ALIGN_RET_ERROR:
                ret = MOSAIC_RET_ERROR;
                break;
            default:
                break;
        }
    }

    return ret;
}


int Mosaic::createMosaic(float &progress, bool &cancelComputation)
{
    if (frames_size <= 0)
    {
        // Haven't accepted any frame in aligner. No need to do blending.
        progress = TIME_PERCENT_ALIGN + TIME_PERCENT_BLEND
                + TIME_PERCENT_FINAL;
        return MOSAIC_RET_OK;
    }

    if (blendingType == Blend::BLEND_TYPE_PAN)
    {

        balanceRotations();

    }

    int ret = Blend::BLEND_RET_ERROR;

    // Blend the mosaic (alignment has already been done)
    if (blender != NULL)
    {
        ret = blender->runBlend((MosaicFrame **) frames, (MosaicFrame **) rframes, 
                frames_size, imageMosaicYVU,
                mosaicWidth, mosaicHeight, progress, cancelComputation);
    }

    switch(ret)
    {
        case Blend::BLEND_RET_ERROR:
        case Blend::BLEND_RET_ERROR_MEMORY:
            ret = MOSAIC_RET_ERROR;
            break;
        case Blend::BLEND_RET_CANCELLED:
            ret = MOSAIC_RET_CANCELLED;
            break;
        case Blend::BLEND_RET_OK:
            ret = MOSAIC_RET_OK;
    }
    return ret;
}

ImageType Mosaic::getMosaic(int &width, int &height)
{
    width = mosaicWidth;
    height = mosaicHeight;

    return imageMosaicYVU;
}



int Mosaic::balanceRotations()
{
    // Normalize to the mean angle of rotation (Smiley face)
    double sineAngle = 0.0;

    for (int i = 0; i < frames_size; i++) sineAngle += frames[i]->trs[0][1];
    sineAngle /= frames_size;
    // Calculate the cosineAngle (1 - sineAngle*sineAngle) = cosineAngle*cosineAngle
    double cosineAngle = sqrt(1.0 - sineAngle*sineAngle);
    double m[3][3] = {
        { cosineAngle, -sineAngle, 0 },
        { sineAngle, cosineAngle, 0},
        { 0, 0, 1}};
    double tmp[3][3];

    for (int i = 0; i < frames_size; i++) {
        memcpy(tmp, frames[i]->trs, sizeof(tmp));
        mult33d(frames[i]->trs, m, tmp);
    }

    return MOSAIC_RET_OK;
}
