/***************************************************************************
 *   Copyright (C) 2006 by Thierry CHARLES   *
 *   thierry@les-charles.net   *
 *                                                                         *
 *   This program 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.                                   *
 *                                                                         *
 *   This program 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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "timageviewer.h"
#include <wx/dcclient.h>
#include <wx/settings.h>
#include <wx/pen.h>
#include <wx/brush.h>

#include "tbitmap.h"

IMPLEMENT_DYNAMIC_CLASS(TImageViewer,wxControl);

BEGIN_EVENT_TABLE(TImageViewer, wxControl)
        EVT_PAINT(TImageViewer::onPaint)
        EVT_SIZE(TImageViewer::onResize)
END_EVENT_TABLE()


TImageViewer::TImageViewer(wxWindow * parent)
    : wxControl(parent, -1, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxTAB_TRAVERSAL),
        bitmap(NULL), cachedImage(NULL), fZoom(1.0)
{
}

TImageViewer::~TImageViewer()
{
    if(this->cachedImage)
        delete this->cachedImage;
    this->cachedImage = NULL;
}

/** calcule la taille optimale du bouton */
wxSize TImageViewer::DoGetBestSize() const
{
    // Do not return any arbitrary default value...
    wxASSERT_MSG( m_widget, wxT("TImageViewer::DoGetBestSize called before creation") );

    if(this->bitmap)
    {
        if(this->fZoom > 0.0)
        {
            int iWidth = int(this->bitmap->GetWidth()*this->fZoom);
            int iHeight = int(this->bitmap->GetHeight()*this->fZoom);

            return wxSize( iWidth, iHeight );
        }
        else
            return wxSize(-1,-1);
    }

    return wxSize(1,1);
}

void TImageViewer::onPaint(wxPaintEvent& WXUNUSED(event))
{
    wxPaintDC dc(this);

    // dessin du bitmap
    if(this->bitmap)
    {
        if(!this->cachedImage)
            this->updateCachedImage();

        // définition de la taille et de la position de l'image
        int iCmpWidth, iCmpHeight;
        this->GetClientSize( &iCmpWidth, &iCmpHeight );
        int iCornerTop = 0;
        int iCornerLeft = 0;
        int iWidth = this->cachedImage->GetWidth();
        int iHeight = this->cachedImage->GetHeight();
        if(iWidth < iCmpWidth)
            iCornerLeft = (iCmpWidth - iWidth) / 2;
        if(iHeight < iCmpHeight)
            iCornerTop = (iCmpHeight - iHeight) / 2;

        dc.DrawBitmap(*this->cachedImage, iCornerLeft, iCornerTop, true);
    }
}

void TImageViewer::updateCachedImage()
{
    if(!this->bitmap)
        return;

    int iWidth = this->bitmap->GetWidth();
    int iHeight = this->bitmap->GetHeight();
    float fCacheZoom = this->fZoom;

    if(this->fZoom <= 0.0)
    {
        int iCmpWidth, iCmpHeight;
        this->GetClientSize( &iCmpWidth, &iCmpHeight );
        if((float(iCmpWidth) / float(iWidth)) > (float(iCmpHeight) / float(iHeight)))
            fCacheZoom = float(iCmpHeight) / float(iHeight);
        else
            fCacheZoom = float(iCmpWidth) / float(iWidth);

        if(fCacheZoom > 1.0)
            fCacheZoom = 1.0;
    }

    iWidth = int(float(iWidth)*fCacheZoom);
    iHeight = int(float(iHeight)*fCacheZoom);

    this->cachedImage = this->bitmap->getResampledCopy(iWidth, iHeight);
//    this->cachedImage = new TBitmap(this->bitmap->ConvertToImage().Scale(iWidth, iHeight,wxIMAGE_QUALITY_HIGH));
}

/** defini l'image a afficher (NULL si aucune) */
void TImageViewer::setBitmap(const TBitmap * bmp)
{
    this->bitmap = bmp;
    if(this->cachedImage)
        delete this->cachedImage;
    this->cachedImage = NULL;
    this->Refresh();
}

/** défini le niveau de zoom a utiliser pour afficher l'image. 0.0 = ajustement automatique */
void TImageViewer::setZoom(float fZoom)
{
    this->fZoom = fZoom;
    if(this->cachedImage)
        delete this->cachedImage;
    this->cachedImage = NULL;
    this->Refresh();
}

void TImageViewer::onResize(wxSizeEvent & event)
{
    if(this->fZoom <= 0.0)
    {
        if(this->cachedImage)
            delete this->cachedImage;
        this->cachedImage = NULL;
    }
    this->Refresh();
}
