/*
 * This source file is part of KEOS (Free 3D Engine)
 * For the latest info, see http://www.keosengine.org/
 * E-mails : thierry.vouriot@keosengine.org, yeri@keosengine.org
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser 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, or go to
 * http://www.gnu.org/copyleft/lesser.txt.
 *
 */

#include "KeosImagesLoader.h"
#include "KeosImage.h"
#include "../Extlibs/DevIL/il.h"
#include "KeosPixelUtils.h"
#include "KeosLogger.h"

namespace Keos
{
    //=======================================================================
    // CImagesLoader implementation
    //=======================================================================
   
    //-----------------------------------------------------------------------
    CImagesLoader::CImagesLoader()
    {
        // DevIL initialization
        ilInit();

        // We indicate that the origin of the images is on the upper-left corner
        ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
        ilEnable(IL_ORIGIN_SET);

        // We authorize the destruction of already existing files, for the saving
        ilEnable(IL_FILE_OVERWRITE);

        // We force the load of the images in 32 bits BGRA
        ilSetInteger(IL_FORMAT_MODE, IL_BGRA);
        ilEnable(IL_FORMAT_SET);
    }

    //-----------------------------------------------------------------------
    CImagesLoader::~CImagesLoader()
    {
        // DevIL shutdown
        ilShutDown();
    }

    //-----------------------------------------------------------------------
    CImage* CImagesLoader::LoadFromFile(const String& strFilename)
    {
        // Generation of a new texture
        ILuint Texture;
        ilGenImages(1, &Texture);
        ilBindImage(Texture);

        // Load of the image
        if (!ilLoadImage(const_cast<ILstring>(strFilename.c_str())))
            LOADINGFAILED_EXCEPT(strFilename, "DevIL error : call to ilLoadImage failed","CImagesLoader::LoadFromFile");
        
        // Image size
        TVector2I Size(ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT));

        // Image pixels
        const uchar* pPixels = ilGetData();

        // Creation of the image
        CImage* Image = new CImage(Size, PXF_A8R8G8B8, pPixels);

        // Delete of the texture
        ilBindImage(0);
        ilDeleteImages(1, &Texture);

        ILogger::Log("Load of the image : %s", strFilename.c_str());

        return Image;
    }
    
    //-----------------------------------------------------------------------
    void CImagesLoader::SaveToFile(const CImage* pObject, const String& strFilename)
    {
        // We create a copy of the image in a compatible format with DevIL (ARGB 32 bits)
        CImage Image(pObject->GetSize(), PXF_A8R8G8B8);
        Image.CopyImage(*pObject);

        Image.Flip();

        // Generation of a new texture
        ILuint Texture;
        ilGenImages(1, &Texture);
        ilBindImage(Texture);

        // Image size
        const TVector2I& Size = Image.GetSize();

        // Completion of the texture with the converted pixels
        if (!ilTexImage(Size.x, Size.y, 1, GetBytesPerPixel(Image.GetFormat()), IL_BGRA, IL_UNSIGNED_BYTE, (void*)Image.GetData()))
            LOADINGFAILED_EXCEPT(strFilename, "DevIL error : call to ilTexImage failed","CImagesLoader::SaveToFile");
        // Save of the texture
        if (!ilSaveImage(const_cast<ILstring>(strFilename.c_str())))
            LOADINGFAILED_EXCEPT(strFilename, "DevIL error : call to ilSaveImage failed","CImagesLoader::SaveToFile");

        // Delete of the texture
        ilBindImage(0);
        ilDeleteImages(1, &Texture);

        ILogger::Log("Save of the image : %s", strFilename.c_str());
    }

} // namespace Keos
