/*
 * File Name: images_document.cpp
 */

/*
 * This file is part of uds-plugin-comics.
 *
 * 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 comics
{

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

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

    close_document();
}

bool ImagesDocument::open_document(const std::string &path, std::map<std::string, std::string> &metadata)
{
	initial_page_num = scanner.scan_archive(path, BY_FILEPATH, true, metadata);

    LOGPRINTF("%d", initial_page_num);

    return true;
}

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

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

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

    return static_cast<unsigned int>(scanner.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 <= scanner.images.size()); 

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

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

    ImagesIter begin = scanner.images.begin();
    ImagesIter end   = scanner.images.end();
    for(ImagesIter iter = begin; iter != end; ++iter)
    {
        delete *iter;
    }
    scanner.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 <= scanner.images.size())
    {
        anchor = scanner.images[page_number - 1]->path;

        LOGPRINTF("%s", scanner.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);

    WARNPRINTF("first_pos[%d] second_pos[%d], result = %d", first_pos, second_pos, first_pos - second_pos);

    return first_pos - second_pos;
}

int ImagesDocument::get_position(const std::string & path)
{
	return scanner.get_position(path);
}

bool ImagesDocument::get_page_name(const std::string & anchor,
                                   std::string & name)
{
    if (has_anchor(anchor))
    {
		int page_num = scanner.get_position(anchor);
		
		if( page_num > 0 )
		{
			char pagename[MAX_PATH_LEN];
			
			snprintf(pagename, sizeof(pagename), "%d", page_num);
			name = pagename;
			
			return true;
		}
    }
    return false;
}

bool ImagesDocument::get_prev_page(std::string & anchor)
{
    ImagesIter begin = scanner.images.begin();
    ImagesIter end   = scanner.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 = scanner.images.begin();
    ImagesIter end   = scanner.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 = scanner.images.begin();
     ImagesIter end   = scanner.images.end();
     ImagesIter iter;
     for(iter = begin; iter != end; ++iter)
     {
         if ((*iter)->path == anchor)
         {
			 Image *image = (*iter);
			
             // The image size is not calculated yet, calculate it now.
             if (!image->is_calculated)
             {
				 image = scanner.update_calc(image->path);
             }
             
             // The valid image's size is greater than zero.
             if ((image->width > 0) && (image->height > 0))
             {
                 width = image->width;
                 height = image->height;

                 return true;
             }
             
			 WARNPRINTF("UDS wants original size, couldn't give it");
             return false;
         }
     }
     
     return false;
}

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

}


