/*
 * File Name: images_document.cpp
 */

/*
 * This file is part of uds-plugin-images.
 *
 * uds-plugin-images is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * uds-plugin-images is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Copyright (C) 2008 iRex Technologies B.V.
 * All rights reserved.
 */

#include <sstream>
#include <iostream>
#include <fstream>
#include <cassert>
#include "images_document.h"
#include "images_scanner.h"
#include "image_page.h"
#include "utils.h"
#include "log.h"

namespace images
{

ImagesDocument::ImagesDocument(void) : initial_page_num(1)
{
    LOGPRINTF("entry");
}

ImagesDocument::~ImagesDocument(void)
{
    LOGPRINTF("entry");

    close_document();
}

bool ImagesDocument::open_document(const std::string &path, bool to_scan_dir)
{
    using namespace images;

    ImagesScanner scanner;

    initial_page_num = scanner.scan_images(path,
                                           to_scan_dir,
                                           false,
                                           BY_FILEPATH, 
                                           true,
                                           images) + 1;
    LOGPRINTF("%d", initial_page_num);

    return true;
}

bool ImagesDocument::is_open()
{
    LOGPRINTF("%d", images.size());

    return (images.size() > 0);
}

unsigned int ImagesDocument::page_count()
{
    LOGPRINTF("%d", images.size());

    return static_cast<unsigned int>(images.size());
}

int ImagesDocument::get_initial_page_num()
{
    return initial_page_num;
}

const ImagePtr ImagesDocument::get_page(const unsigned int page_number)
{
    assert(page_number >= 1 && page_number <= images.size()); 

    LOGPRINTF("page[%d] %s", 
            page_number, 
            images[page_number - 1]->path.c_str());
    
    return images[page_number - 1];
}

bool ImagesDocument::close_document()
{
    LOGPRINTF("entry");

    ImagesIter begin = images.begin();
    ImagesIter end   = images.end();
    for(ImagesIter iter = begin; iter != end; ++iter)
    {
        delete *iter;
    }
    images.clear();
    return true;
}

bool ImagesDocument::get_anchor_of_page(const unsigned int page_number,
                                       std::string & anchor)
{
    LOGPRINTF("entry %d", page_number);

    if (page_number >= 1 && page_number <= images.size())
    {
        anchor = images[page_number - 1]->path;

        LOGPRINTF("%s", images[page_number -1]->path.c_str());

        return true;
    }
    else
    {
        return false;
    }
}

bool ImagesDocument::has_anchor(const std::string & anchor)
{
    LOGPRINTF("%s", anchor.c_str());

    return (get_position(anchor) >= 0);
}

int ImagesDocument::compare_anchor(const std::string & first,
                                  const std::string & second)
{
    int first_pos = get_position(first);
    int second_pos = get_position(second);

    LOGPRINTF("first_pos[%d] second_pos[%d]", first_pos, second_pos);

    return first_pos - second_pos;
}

int ImagesDocument::get_position(const std::string & path)
{
    ImagesIter begin = images.begin();
    ImagesIter end   = images.end();
    for(ImagesIter iter = begin; iter != end; ++iter)
    {
        if ((*iter)->path == path)
        {
            LOGPRINTF("%d", static_cast<int>((iter - begin) + 1));

            return static_cast<int>((iter - begin) + 1);
        }
    }
    return -1;
}

bool ImagesDocument::get_page_name(const std::string & anchor,
                                   std::string & name)
{
    if (has_anchor(anchor))
    {
        char filename[MAX_PATH_LEN];
        if (get_file_name(anchor.c_str(), filename, MAX_PATH_LEN))
        {
            name = filename;
            return true;
        }
    }
    return false;
}

bool ImagesDocument::get_prev_page(std::string & anchor)
{
    ImagesIter begin = images.begin();
    ImagesIter end   = images.end();
    ImagesIter iter;
    for(iter = begin; iter != end; ++iter)
    {
        if ((*iter)->path == anchor)
        {
            break;
        }
    }
    
    // Check the iter position.
    if (iter == end || iter == begin)
    {
        return false;
    }
    anchor = (*--iter)->path;

    LOGPRINTF("%s", anchor.c_str());

    return true;
}

bool ImagesDocument::get_next_page(std::string & anchor)
{
    ImagesIter begin = images.begin();
    ImagesIter end   = images.end();
    ImagesIter iter;
    for(iter = begin; iter != end; ++iter)
    {
        if ((*iter)->path == anchor)
        {
            break;
        }
    }
    
    if (iter == end || ++iter == end)
    {
        return false;
    }
    anchor = (*iter)->path;

    LOGPRINTF("%s", anchor.c_str());

    return true;
}

bool ImagesDocument::get_original_size(const std::string &anchor, 
                                       unsigned int & width,
                                       unsigned int & height)
{
     ImagesIter begin = images.begin();
     ImagesIter end   = images.end();
     ImagesIter iter;
     for(iter = begin; iter != end; ++iter)
     {
         if ((*iter)->path == anchor)
         {
             // The image size is not calculated yet, calculate it now.
             if (((*iter)->width == -1) || ((*iter)->height == -1))
             {
                 ImagesScanner::get_size((*iter)->path, 
                                         &(*iter)->width, 
                                         &(*iter)->height);
             }
             
             // The valid image's size is greater than zero.
             if (((*iter)->width > 0) && ((*iter)->height > 0))
             {
                 width = (*iter)->width;
                 height = (*iter)->height;
                 
                 return true;
             }
             
             return false;
         }
     }
     
     return false;
}

bool ImagesDocument::get_original_rotation(const std::string & anchor,
                                           PluginRotationDegree & rotation)
{
     ImagesIter begin = images.begin();
     ImagesIter end   = images.end();
     ImagesIter iter;
     for(iter = begin; iter != end; ++iter)
     {
         if ((*iter)->path == anchor)
         {
             // The image rotation is not calculated yet, calculate it now.
             if ( !((*iter)->is_rotation_calculated) )
             {
                 ImagesScanner::get_original_rotation((*iter)->path, (*iter)->rotation);
                 (*iter)->is_rotation_calculated = true;
             }

             rotation = (*iter)->rotation;
             
             return true;
         }
     }
     return false;
}

}


