/*
 * MACDRV Cocoa clipboard code
 *
 * Copyright 2012, 2013 Ken Thomases for CodeWeavers Inc.
 *
 * 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 "macdrv_cocoa.h"
#import "cocoa_app.h"
#import "cocoa_event.h"


static int owned_change_count = -1;

static NSArray* BitmapOutputTypes;
static NSDictionary* BitmapOutputTypeMap;
static dispatch_once_t BitmapOutputTypesInitOnce;


/***********************************************************************
 *              macdrv_is_pasteboard_owner
 */
int macdrv_is_pasteboard_owner(void)
{
    __block int ret;

    OnMainThread(^{
        NSPasteboard* pb = [NSPasteboard generalPasteboard];
        ret = ([pb changeCount] == owned_change_count);
    });

    return ret;
}


/***********************************************************************
 *              macdrv_copy_pasteboard_types
 *
 * Returns an array of UTI strings for the types of data available on
 * the pasteboard, or NULL on error.  The caller is responsible for
 * releasing the returned array with CFRelease().
 */
CFArrayRef macdrv_copy_pasteboard_types(CFTypeRef pasteboard)
{
    NSPasteboard* pb = (NSPasteboard*)pasteboard;
    __block CFArrayRef ret = NULL;
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    dispatch_once(&BitmapOutputTypesInitOnce, ^{
        NSArray* bitmapFileTypes = [NSArray arrayWithObjects:
                                    [NSNumber numberWithUnsignedInteger:NSTIFFFileType],
                                    [NSNumber numberWithUnsignedInteger:NSPNGFileType],
                                    [NSNumber numberWithUnsignedInteger:NSBMPFileType],
                                    [NSNumber numberWithUnsignedInteger:NSGIFFileType],
                                    [NSNumber numberWithUnsignedInteger:NSJPEGFileType],
                                    nil];

        BitmapOutputTypes = [[NSArray alloc] initWithObjects:@"public.tiff", @"public.png",
                             @"com.microsoft.bmp", @"com.compuserve.gif", @"public.jpeg", nil];

        BitmapOutputTypeMap = [[NSDictionary alloc] initWithObjects:bitmapFileTypes
                                                            forKeys:BitmapOutputTypes];
    });

    OnMainThread(^{
        @try
        {
            NSPasteboard* local_pb = pb;
            NSArray* types;

            if (!local_pb) local_pb = [NSPasteboard generalPasteboard];
            types = [local_pb types];

            // If there are any types understood by NSBitmapImageRep, then we
            // can offer all of the types that it can output, too.  For example,
            // if TIFF is on the pasteboard, we can offer PNG, BMP, etc. to the
            // Windows program.  We'll convert on demand.
            if ([types firstObjectCommonWithArray:[NSBitmapImageRep imageTypes]] ||
                [types firstObjectCommonWithArray:[NSBitmapImageRep imagePasteboardTypes]])
            {
                NSMutableArray* newTypes = [BitmapOutputTypes mutableCopy];
                [newTypes removeObjectsInArray:types];
                types = [types arrayByAddingObjectsFromArray:newTypes];
                [newTypes release];
            }

            ret = (CFArrayRef)[types copy];
        }
        @catch (id e)
        {
            ERR(@"Exception discarded while copying pasteboard types: %@\n", e);
        }
    });

    [pool release];
    return ret;
}


/***********************************************************************
 *              macdrv_copy_pasteboard_data
 *
 * Returns the pasteboard data for a specified type, or NULL on error or
 * if there's no such type on the pasteboard.  The caller is responsible
 * for releasing the returned data object with CFRelease().
 */
CFDataRef macdrv_copy_pasteboard_data(CFTypeRef pasteboard, CFStringRef type)
{
    NSPasteboard* pb = (NSPasteboard*)pasteboard;
    __block NSData* ret = nil;

    OnMainThread(^{
        @try
        {
            NSPasteboard* local_pb = pb;
            if (!local_pb) local_pb = [NSPasteboard generalPasteboard];
            if ([local_pb availableTypeFromArray:[NSArray arrayWithObject:(NSString*)type]])
                ret = [[local_pb dataForType:(NSString*)type] copy];
            else
            {
                NSNumber* bitmapType = [BitmapOutputTypeMap objectForKey:(NSString*)type];
                if (bitmapType)
                {
                    NSArray* reps = [NSBitmapImageRep imageRepsWithPasteboard:local_pb];
                    ret = [NSBitmapImageRep representationOfImageRepsInArray:reps
                                                                   usingType:[bitmapType unsignedIntegerValue]
                                                                  properties:nil];
                    ret = [ret copy];
                }
            }
        }
        @catch (id e)
        {
            ERR(@"Exception discarded while copying pasteboard types: %@\n", e);
        }
    });

    return (CFDataRef)ret;
}


/***********************************************************************
 *              macdrv_clear_pasteboard
 *
 * Takes ownership of the Mac pasteboard and clears it of all data types.
 */
void macdrv_clear_pasteboard(void)
{
    OnMainThreadAsync(^{
        @try
        {
            NSPasteboard* pb = [NSPasteboard generalPasteboard];
            owned_change_count = [pb declareTypes:[NSArray array] owner:nil];
        }
        @catch (id e)
        {
            ERR(@"Exception discarded while clearing pasteboard: %@\n", e);
        }
    });
}


/***********************************************************************
 *              macdrv_set_pasteboard_data
 *
 * Sets the pasteboard data for a specified type.  Replaces any data of
 * that type already on the pasteboard.  If data is NULL, promises the
 * type.
 *
 * Returns 0 on error, non-zero on success.
 */
int macdrv_set_pasteboard_data(CFStringRef type, CFDataRef data, macdrv_window w)
{
    __block int ret = 0;
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        @try
        {
            NSPasteboard* pb = [NSPasteboard generalPasteboard];
            NSInteger change_count = [pb addTypes:[NSArray arrayWithObject:(NSString*)type]
                                            owner:window];
            if (change_count)
            {
                owned_change_count = change_count;
                if (data)
                    ret = [pb setData:(NSData*)data forType:(NSString*)type];
                else
                    ret = 1;
            }
        }
        @catch (id e)
        {
            ERR(@"Exception discarded while copying pasteboard types: %@\n", e);
        }
    });

    return ret;
}
