/*
 * MSCMS - Color Management System for Wine
 *
 * Copyright 2004, 2005, 2008 Hans Leidekker
 *
 * This library 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.1 of the License, or (at your option) any later version.
 *
 * This library 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 library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/debug.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "icm.h"

#include "mscms_priv.h"

#ifdef HAVE_LCMS

static CRITICAL_SECTION MSCMS_handle_cs;
static CRITICAL_SECTION_DEBUG MSCMS_handle_cs_debug =
{
    0, 0, &MSCMS_handle_cs,
    { &MSCMS_handle_cs_debug.ProcessLocksList,
      &MSCMS_handle_cs_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": MSCMS_handle_cs") }
};
static CRITICAL_SECTION MSCMS_handle_cs = { &MSCMS_handle_cs_debug, -1, 0, 0, 0, 0 };

static struct profile *profiletable;
static struct transform *transformtable;

static unsigned int num_profile_handles;
static unsigned int num_transform_handles;

WINE_DEFAULT_DEBUG_CHANNEL(mscms);

void free_handle_tables( void )
{
    HeapFree( GetProcessHeap(), 0, profiletable );
    profiletable = NULL;
    num_profile_handles = 0;

    HeapFree( GetProcessHeap(), 0, transformtable );
    transformtable = NULL;
    num_transform_handles = 0;

    DeleteCriticalSection( &MSCMS_handle_cs );
}

struct profile *grab_profile( HPROFILE handle )
{
    DWORD_PTR index;

    EnterCriticalSection( &MSCMS_handle_cs );

    index = (DWORD_PTR)handle - 1;
    if (index > num_profile_handles)
    {
        LeaveCriticalSection( &MSCMS_handle_cs );
        return NULL;
    }
    return &profiletable[index];
}

void release_profile( struct profile *profile )
{
    LeaveCriticalSection( &MSCMS_handle_cs );
}

struct transform *grab_transform( HTRANSFORM handle )
{
    DWORD_PTR index;

    EnterCriticalSection( &MSCMS_handle_cs );

    index = (DWORD_PTR)handle - 1;
    if (index > num_transform_handles)
    {
        LeaveCriticalSection( &MSCMS_handle_cs );
        return NULL;
    }
    return &transformtable[index];
}

void release_transform( struct transform *transform )
{
    LeaveCriticalSection( &MSCMS_handle_cs );
}

static HPROFILE alloc_profile_handle( void )
{
    DWORD_PTR index;
    struct profile *p;
    unsigned int count = 128;

    for (index = 0; index < num_profile_handles; index++)
    {
        if (!profiletable[index].iccprofile) return (HPROFILE)(index + 1);
    }
    if (!profiletable)
    {
        p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(struct profile) );
    }
    else
    {
        count = num_profile_handles * 2;
        p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, profiletable, count * sizeof(struct profile) );
    }
    if (!p) return NULL;

    profiletable = p;
    num_profile_handles = count;

    return (HPROFILE)(index + 1);
}

HPROFILE create_profile( struct profile *profile )
{
    HPROFILE handle;

    EnterCriticalSection( &MSCMS_handle_cs );

    if ((handle = alloc_profile_handle()))
    {
        DWORD_PTR index = (DWORD_PTR)handle - 1;
        profiletable[index] = *profile;
    }
    LeaveCriticalSection( &MSCMS_handle_cs );
    return handle;
}

BOOL close_profile( HPROFILE handle )
{
    DWORD_PTR index;
    struct profile *profile;

    EnterCriticalSection( &MSCMS_handle_cs );

    index = (DWORD_PTR)handle - 1;
    if (index > num_profile_handles)
    {
        LeaveCriticalSection( &MSCMS_handle_cs );
        return FALSE;
    }
    profile = &profiletable[index];

    if (profile->file != INVALID_HANDLE_VALUE)
    {
        if (profile->access & PROFILE_READWRITE)
        {
            DWORD written, size = MSCMS_get_profile_size( profile->iccprofile );

            if (SetFilePointer( profile->file, 0, NULL, FILE_BEGIN ) ||
                !WriteFile( profile->file, profile->iccprofile, size, &written, NULL ) ||
                written != size)
            {
                ERR( "Unable to write color profile\n" );
            }
        }
        CloseHandle( profile->file );
    }
    cmsCloseProfile( profile->cmsprofile );
    HeapFree( GetProcessHeap(), 0, profile->iccprofile );

    memset( profile, 0, sizeof(struct profile) );

    LeaveCriticalSection( &MSCMS_handle_cs );
    return TRUE;
}

static HTRANSFORM alloc_transform_handle( void )
{
    DWORD_PTR index;
    struct transform *p;
    unsigned int count = 128;

    for (index = 0; index < num_transform_handles; index++)
    {
        if (!transformtable[index].cmstransform) return (HTRANSFORM)(index + 1);
    }
    if (!transformtable)
    {
        p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(struct transform) );
    }
    else
    {
        count = num_transform_handles * 2;
        p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, transformtable, count * sizeof(struct transform) );
    }
    if (!p) return NULL;

    transformtable = p;
    num_transform_handles = count;

    return (HTRANSFORM)(index + 1);
}

HTRANSFORM create_transform( struct transform *transform )
{
    HTRANSFORM handle;

    EnterCriticalSection( &MSCMS_handle_cs );

    if ((handle = alloc_transform_handle()))
    {
        DWORD_PTR index = (DWORD_PTR)handle - 1;
        transformtable[index] = *transform;
    }
    LeaveCriticalSection( &MSCMS_handle_cs );
    return handle;
}

BOOL close_transform( HTRANSFORM handle )
{
    DWORD_PTR index;
    struct transform *transform;

    EnterCriticalSection( &MSCMS_handle_cs );

    index = (DWORD_PTR)handle - 1;
    if (index > num_transform_handles)
    {
        LeaveCriticalSection( &MSCMS_handle_cs );
        return FALSE;
    }
    transform = &transformtable[index];

    cmsDeleteTransform( transform->cmstransform );
    memset( transform, 0, sizeof(struct transform) );

    LeaveCriticalSection( &MSCMS_handle_cs );
    return TRUE;
}

#endif /* HAVE_LCMS */
