/*
    pygame - Python Game Library
    Copyright (C) 2006, 2007 Rene Dudfield, Marcus von Appen

    Originally written and put in the public domain by Sam Lantinga.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

static unsigned short InputGroup;
#define MAX_CHUNK_SIZE INT_MAX

/**
 * \brief Converts the passed type into a system specific type to use
 *        for the clipboard.
 *
 * \param type The type to convert.
 * \return A system specific type.
 */
static uint32_t
_convert_format (char *type)
{
  switch (type)
    {
    case PYGAME_SCRAP_TEXT:
        return Ph_CL_TEXT;
    default: /* PYGAME_SCRAP_BMP et al. */
    {
        /* TODO */
        return 0;
    }
    }
}

int
pygame_scrap_init (void)
{
    SDL_SysWMinfo info;
    int retval = 0;

    /* Grab the window manager specific information */
    SDL_SetError ("SDL is not running on known window manager");

    SDL_VERSION (&info.version);
    if (SDL_GetWMInfo (&info))
    {
        /* Save the information for later use */
        InputGroup = PhInputGroup (NULL);
        retval = 1;
    }
    if (retval)
        _scrapinitialized = 1;

    return retval;
}

int
pygame_scrap_lost (void)
{
    if (!pygame_scrap_initialized ())
    {
        PyErr_SetString (PyExc_SDLError, "scrap system not initialized.");
        return 0;
    }
    return (PhInputGroup (NULL) != InputGroup);
}

int
pygame_scrap_put (char *type, int srclen, char *src)
{
    uint32_t format;
    int nulledlen = srclen + 1;

    if (!pygame_scrap_initialized ())
    {
        PyErr_SetString (PyExc_SDLError, "scrap system not initialized.");
        return 0;
    }

    format = _convert_format (type);

    /* Clear old buffer and copy the new content. */
    if (_clipbuffer)
        free (_clipbuffer);

    _clipbuffer = malloc (nulledlen);
    if (!_clipbuffer)
        return 0; /* Allocation failed. */
    memset (_clipbuffer, 0, nulledlen);
    memcpy (_clipbuffer, src, srclen);
    _clipsize = srclen;
    _cliptype = format;

#if (_NTO_VERSION < 620) /* Before 6.2.0 releases. */
    {
        PhClipHeader clheader = { Ph_CLIPBOARD_TYPE_TEXT, 0, NULL };
        int* cldata;
        int status;
        
        cldata = (int *) _clipbuffer;
        *cldata = type;
        clheader.data = _clipbuffer;
        if (dstlen > 65535)
            clheader.length = 65535; /* Maximum photon clipboard size. :( */
        else
            clheader.length = nulledlen;
        
        status = PhClipboardCopy (InputGroup, 1, &clheader);
        if (status == -1)
        {
            /* Could not access the clipboard, raise an error. */
            CLEAN_CLIP_BUFFER ();
            return 0;
        }
    }

#else /* 6.2.0 and 6.2.1 and future releases. */
    {
        PhClipboardHdr clheader = { Ph_CLIPBOARD_TYPE_TEXT, 0, NULL };
        int* cldata;
        int status;
        
        cldata = (int *) _clipbuffer;
        *cldata = type;
        clheader.data = _clipbuffer;
        clheader.length = nulledlen;

        status = PhClipboardWrite (InputGroup, 1, &clheader);
        if (status == -1)
        {
            /* Could not access the clipboard, raise an error. */
            CLEAN_CLIP_BUFFER ();
            return 0;
        }
    }
#endif
    return 1;
}

char*
pygame_get_scrap (char *type)
{
    uint32_t format = _convert_format (type);
    char *retval = NULL;

    if (!pygame_scrap_initialized ())
    {
        PyErr_SetString (PyExc_SDLError, "scrap system not initialized.");
        return 0;
    }

    /* If we are the owner, simply return the clip buffer, if it matches
     * the request type. */
    if (!pygame_scrap_lost ())
    {
        if (format != _cliptype)
            return NULL;

        if (_clipbuffer)
        {
            retval = malloc (_clipsize + 1);
            if (!retval)
                return NULL;
            memset (retval, 0, _clipsize + 1);
            memcpy (retval, _clipbuffer, _clipsize + 1);
            return retval;
        }
        return NULL;
    }

#if (_NTO_VERSION < 620) /* before 6.2.0 releases */
    {
        void *clhandle;
        PhClipHeader *clheader;
        int *cldata;
        
        clhandle = PhClipboardPasteStart (InputGroup);
        
        if (clhandle)
        {
            clheader = PhClipboardPasteType (clhandle, Ph_CLIPBOARD_TYPE_TEXT);
            if (clheader)
            {
                cldata = clheader->data;
                if (*cldata == type)
                    retval = malloc (clheader->length + 1);
                
                if (retval)
                {
                    memset (retval, 0, clheader->length + 1);
                    memcpy (retval, cldata, clheader->length + 1);
                }
            }
            PhClipboardPasteFinish (clhandle);
        }
    }
#else /* 6.2.0 and 6.2.1 and future releases */
    {
        void* clhandle;
        PhClipboardHdr* clheader;
        int* cldata;
        
        clheader = PhClipboardRead (InputGroup, Ph_CLIPBOARD_TYPE_TEXT);
        if (clheader)
        {
            cldata = clheader->data;
            if (*cldata == type)
                retval = malloc (clheader->length + 1);
            
            if (retval)
            {
                memset (retval, 0, clheader->length + 1);
                memcpy (retval, cldata, clheader->length + 1);
            }
            /* According to the QNX 6.x docs, the clheader pointer is a
             * newly created one that must be freed manually. */
            free (clheader->data);
            free (clheader);
        }
    }
#endif

    return retval;
}


char**
pygame_scrap_get_types (void)
{
    return NULL;
}

int
pygame_scrap_contains (char *type)
{
    return 0;
}
