#include "SkTypes.h"

#if defined(SK_BUILD_FOR_MAC) && !defined(SK_USE_WXWIDGETS)

#include <Carbon/Carbon.h>
#include "SkCGUtils.h"

#include "SkWindow.h"
#include "SkCanvas.h"
#include "SkOSMenu.h"
#include "SkTime.h"

#include "SkGraphics.h"
#include <new.h>

static void (*gPrevNewHandler)();

extern "C" {
	static void sk_new_handler()
	{
		if (SkGraphics::SetFontCacheUsed(0))
			return;
		if (gPrevNewHandler)
			gPrevNewHandler();
		else
			sk_throw();
	}
}

static SkOSWindow* gCurrOSWin;
static EventTargetRef gEventTarget;
static EventQueueRef gCurrEventQ;

static OSStatus MyDrawEventHandler(EventHandlerCallRef myHandler,
                                   EventRef event, void *userData) {
	// NOTE: GState is save/restored by the HIView system doing the callback,
    // so the draw handler doesn't need to do it
    
	OSStatus status = noErr;
	CGContextRef context;
	HIRect		bounds;
    
	// Get the CGContextRef
	status = GetEventParameter (event, kEventParamCGContextRef, 
                                typeCGContextRef, NULL, 
                                sizeof (CGContextRef),
                                NULL,
                                &context);
    
	if (status != noErr) {
		SkDebugf("Got error %d getting the context!\n", status);
		return status;
	}		
    
	// Get the bounding rectangle
	HIViewGetBounds ((HIViewRef) userData, &bounds);
	
    gCurrOSWin->doPaint(context);
	return status;
}

#define SK_MacEventClass			FOUR_CHAR_CODE('SKec')
#define SK_MacEventKind				FOUR_CHAR_CODE('SKek')
#define SK_MacEventParamName		FOUR_CHAR_CODE('SKev')
#define SK_MacEventSinkIDParamName	FOUR_CHAR_CODE('SKes')

static void set_bindingside(HISideBinding* side, HIViewRef parent, HIBindingKind kind) {
    side->toView = parent;
    side->kind = kind;
    side->offset = 0;
}

static void set_axisscale(HIAxisScale* axis, HIViewRef parent) {
    axis->toView = parent;
    axis->kind = kHILayoutScaleAbsolute;
    axis->ratio = 1;
}

static void set_axisposition(HIAxisPosition* pos, HIViewRef parent, HIPositionKind kind) {
    pos->toView = parent;
    pos->kind = kind;
    pos->offset = 0;
}

SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd)
{
	OSStatus    result;
    WindowRef   wr = (WindowRef)hWnd;
    
    HIViewRef imageView, parent;
    HIViewRef rootView = HIViewGetRoot(wr);
    HIViewFindByID(rootView, kHIViewWindowContentID, &parent);
    result = HIImageViewCreate(NULL, &imageView);
	SkASSERT(result == noErr);
    
    result = HIViewAddSubview(parent, imageView);
	SkASSERT(result == noErr);

    fHVIEW = imageView;

    HIViewSetVisible(imageView, true);
    HIViewPlaceInSuperviewAt(imageView, 0, 0);

    if (true) {
        HILayoutInfo layout;
        layout.version = kHILayoutInfoVersionZero;
        set_bindingside(&layout.binding.left, parent, kHILayoutBindLeft);
        set_bindingside(&layout.binding.top, parent, kHILayoutBindTop);
        set_bindingside(&layout.binding.right, parent, kHILayoutBindRight);
        set_bindingside(&layout.binding.bottom, parent, kHILayoutBindBottom);
        set_axisscale(&layout.scale.x, parent);
        set_axisscale(&layout.scale.y, parent);
        set_axisposition(&layout.position.x, parent, kHILayoutPositionLeft);
        set_axisposition(&layout.position.y, rootView, kHILayoutPositionTop);
        HIViewSetLayoutInfo(imageView, &layout);
    }

    HIImageViewSetOpaque(imageView, true);
    HIImageViewSetScaleToFit(imageView, false);

	static const EventTypeSpec  gTypes[] = {
		{ kEventClassKeyboard,  kEventRawKeyDown			},
        { kEventClassKeyboard,  kEventRawKeyUp              },
		{ kEventClassMouse,		kEventMouseDown				},
		{ kEventClassMouse,		kEventMouseDragged			},
		{ kEventClassMouse,		kEventMouseUp				},
		{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent   },
		{ kEventClassWindow,	kEventWindowBoundsChanged	},
//		{ kEventClassWindow,	kEventWindowDrawContent		},
		{ SK_MacEventClass,		SK_MacEventKind				}
	};

	EventHandlerUPP handlerUPP = NewEventHandlerUPP(SkOSWindow::EventHandler);
	int				count = SK_ARRAY_COUNT(gTypes);

	result = InstallEventHandler(GetWindowEventTarget(wr), handlerUPP,
						count, gTypes, this, nil);
	SkASSERT(result == noErr);
    
	gCurrOSWin = this;
	gCurrEventQ = GetCurrentEventQueue();
	gEventTarget = GetWindowEventTarget(wr);

	static bool gOnce = true;
	if (gOnce) {
		gOnce = false;
		gPrevNewHandler = set_new_handler(sk_new_handler);
	}
}

void SkOSWindow::doPaint(void* ctx)
{
#if 0
	this->update(NULL);

    const SkBitmap& bm = this->getBitmap();
    CGImageRef img = SkCreateCGImageRef(bm);

    if (img) {
        CGRect r = CGRectMake(0, 0, bm.width(), bm.height());

        CGContextRef cg = reinterpret_cast<CGContextRef>(ctx);

        CGContextSaveGState(cg);
        CGContextTranslateCTM(cg, 0, r.size.height);
        CGContextScaleCTM(cg, 1, -1);

        CGContextDrawImage(cg, r, img);
        
        CGContextRestoreGState(cg);

        CGImageRelease(img);
    }
#endif
}

void SkOSWindow::updateSize()
{
	Rect	r;
	
	GetWindowBounds((WindowRef)fHWND, kWindowContentRgn, &r);
	this->resize(r.right - r.left, r.bottom - r.top);
    
#if 0
    HIRect    frame;
    HIViewRef imageView = (HIViewRef)getHVIEW();
    HIViewRef parent = HIViewGetSuperview(imageView);
  
    HIViewGetBounds(imageView, &frame);
    SkDebugf("------ %d bounds %g %g %g %g\n", r.right - r.left,
             frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
#endif
}

void SkOSWindow::onHandleInval(const SkIRect& r)
{
    SkEvent* evt = new SkEvent("inval-imageview");
    evt->post(this->getSinkID());
}

bool SkOSWindow::onEvent(const SkEvent& evt) {
    if (evt.isType("inval-imageview")) {
        this->update(NULL);

        const SkBitmap& bm = this->getBitmap();

        CGImageRef img = SkCreateCGImageRef(bm);
        HIImageViewSetImage((HIViewRef)getHVIEW(), img);
        CGImageRelease(img);
        return true;
    }
    return INHERITED::onEvent(evt);
}

void SkOSWindow::onSetTitle(const char title[])
{
    CFStringRef str = CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8);
    SetWindowTitleWithCFString((WindowRef)fHWND, str);
    CFRelease(str);
}

void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu)
{
}

static void getparam(EventRef inEvent, OSType name, OSType type, UInt32 size, void* data)
{
	EventParamType  actualType;
	UInt32			actualSize;
	OSStatus		status;

	status = GetEventParameter(inEvent, name, type, &actualType, size, &actualSize, data);
	SkASSERT(status == noErr);
	SkASSERT(actualType == type);
	SkASSERT(actualSize == size);
}

enum {
	SK_MacReturnKey		= 36,
	SK_MacDeleteKey		= 51,
	SK_MacEndKey		= 119,
	SK_MacLeftKey		= 123,
	SK_MacRightKey		= 124,
	SK_MacDownKey		= 125,
	SK_MacUpKey			= 126,
    
    SK_Mac0Key          = 0x52,
    SK_Mac1Key          = 0x53,
    SK_Mac2Key          = 0x54,
    SK_Mac3Key          = 0x55,
    SK_Mac4Key          = 0x56,
    SK_Mac5Key          = 0x57,
    SK_Mac6Key          = 0x58,
    SK_Mac7Key          = 0x59,
    SK_Mac8Key          = 0x5b,
    SK_Mac9Key          = 0x5c
};
	
static SkKey raw2key(UInt32 raw)
{
	static const struct {
		UInt32  fRaw;
		SkKey   fKey;
	} gKeys[] = {
		{ SK_MacUpKey,		kUp_SkKey		},
		{ SK_MacDownKey,	kDown_SkKey		},
		{ SK_MacLeftKey,	kLeft_SkKey		},
		{ SK_MacRightKey,   kRight_SkKey	},
		{ SK_MacReturnKey,  kOK_SkKey		},
		{ SK_MacDeleteKey,  kBack_SkKey		},
		{ SK_MacEndKey,		kEnd_SkKey		},
        { SK_Mac0Key,       k0_SkKey        },
        { SK_Mac1Key,       k1_SkKey        },
        { SK_Mac2Key,       k2_SkKey        },
        { SK_Mac3Key,       k3_SkKey        },
        { SK_Mac4Key,       k4_SkKey        },
        { SK_Mac5Key,       k5_SkKey        },
        { SK_Mac6Key,       k6_SkKey        },
        { SK_Mac7Key,       k7_SkKey        },
        { SK_Mac8Key,       k8_SkKey        },
        { SK_Mac9Key,       k9_SkKey        }
	};
	
	for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++)
		if (gKeys[i].fRaw == raw)
			return gKeys[i].fKey;
	return kNONE_SkKey;
}

static void post_skmacevent()
{
	EventRef	ref;
	OSStatus	status = CreateEvent(nil, SK_MacEventClass, SK_MacEventKind, 0, 0, &ref);
	SkASSERT(status == noErr);
	
#if 0
	status = SetEventParameter(ref, SK_MacEventParamName, SK_MacEventParamName, sizeof(evt), &evt);
	SkASSERT(status == noErr);
	status = SetEventParameter(ref, SK_MacEventSinkIDParamName, SK_MacEventSinkIDParamName, sizeof(sinkID), &sinkID);
	SkASSERT(status == noErr);
#endif
	
	EventTargetRef target = gEventTarget;
	SetEventParameter(ref, kEventParamPostTarget, typeEventTargetRef, sizeof(target), &target);
	SkASSERT(status == noErr);
	
	status = PostEventToQueue(gCurrEventQ, ref, kEventPriorityStandard);
	SkASSERT(status == noErr);

	ReleaseEvent(ref);
}

pascal OSStatus SkOSWindow::EventHandler( EventHandlerCallRef inHandler, EventRef inEvent, void* userData )
{
	SkOSWindow* win = (SkOSWindow*)userData;
	OSStatus	result = eventNotHandledErr;
	UInt32		wClass = GetEventClass(inEvent);
	UInt32		wKind = GetEventKind(inEvent);

	gCurrOSWin = win;	// will need to be in TLS. Set this so PostEvent will work

	switch (wClass) {
        case kEventClassMouse: {
			Point   pt;
			getparam(inEvent, kEventParamMouseLocation, typeQDPoint, sizeof(pt), &pt);
			SetPortWindowPort((WindowRef)win->getHWND());
			GlobalToLocal(&pt);

			switch (wKind) {
                case kEventMouseDown:
                    (void)win->handleClick(pt.h, pt.v, Click::kDown_State);
                    result = noErr;
                    break;
                case kEventMouseDragged:
                    (void)win->handleClick(pt.h, pt.v, Click::kMoved_State);
                    result = noErr;
                    break;
                case kEventMouseUp:
                    (void)win->handleClick(pt.h, pt.v, Click::kUp_State);
                    result = noErr;
                    break;
                default:
                    break;
			}
            break;
		}
        case kEventClassKeyboard:
            if (wKind == kEventRawKeyDown) {
                UInt32  raw;
                getparam(inEvent, kEventParamKeyCode, typeUInt32, sizeof(raw), &raw);
                SkKey key = raw2key(raw);
                if (key != kNONE_SkKey)
                    (void)win->handleKey(key);
            } else if (wKind == kEventRawKeyUp) {
                UInt32 raw;
                getparam(inEvent, kEventParamKeyCode, typeUInt32, sizeof(raw), &raw);
                SkKey key = raw2key(raw);
                if (key != kNONE_SkKey)
                    (void)win->handleKeyUp(key);
            }
            break;
        case kEventClassTextInput:
            if (wKind == kEventTextInputUnicodeForKeyEvent) {
                UInt16  uni;
                getparam(inEvent, kEventParamTextInputSendText, typeUnicodeText, sizeof(uni), &uni);
                win->handleChar(uni);
            }
            break;
        case kEventClassWindow:
            switch (wKind) {
                case kEventWindowBoundsChanged:
                    win->updateSize();
                    break;
                case kEventWindowDrawContent: {
                    CGContextRef cg;
                    result = GetEventParameter(inEvent,
                                               kEventParamCGContextRef,
                                               typeCGContextRef,
                                               NULL,
                                               sizeof (CGContextRef),
                                               NULL,
                                               &cg);
                    if (result != 0) {
                        cg = NULL;
                    }
                    win->doPaint(cg);
                    break;
                }
                default:
                    break;
            }
            break;
        case SK_MacEventClass: {
            SkASSERT(wKind == SK_MacEventKind);
            if (SkEvent::ProcessEvent()) {
                    post_skmacevent();
            }
    #if 0
            SkEvent*		evt;
            SkEventSinkID	sinkID;
            getparam(inEvent, SK_MacEventParamName, SK_MacEventParamName, sizeof(evt), &evt);
            getparam(inEvent, SK_MacEventSinkIDParamName, SK_MacEventSinkIDParamName, sizeof(sinkID), &sinkID);
    #endif
            result = noErr;
            break;
        }
        default:
            break;
	}
	if (result == eventNotHandledErr) {
		result = CallNextEventHandler(inHandler, inEvent);
    }
	return result;
}

///////////////////////////////////////////////////////////////////////////////////////

void SkEvent::SignalNonEmptyQueue()
{
	post_skmacevent();
//	SkDebugf("signal nonempty\n");
}

static TMTask	gTMTaskRec;
static TMTask*	gTMTaskPtr;

static void sk_timer_proc(TMTask* rec)
{
	SkEvent::ServiceQueueTimer();
//	SkDebugf("timer task fired\n");
}

void SkEvent::SignalQueueTimer(SkMSec delay)
{
	if (gTMTaskPtr)
	{
		RemoveTimeTask((QElem*)gTMTaskPtr);
		DisposeTimerUPP(gTMTaskPtr->tmAddr);
		gTMTaskPtr = nil;
	}
	if (delay)
	{
		gTMTaskPtr = &gTMTaskRec;
		memset(gTMTaskPtr, 0, sizeof(gTMTaskRec));
		gTMTaskPtr->tmAddr = NewTimerUPP(sk_timer_proc);
		OSErr err = InstallTimeTask((QElem*)gTMTaskPtr);
//		SkDebugf("installtimetask of %d returned %d\n", delay, err);
		PrimeTimeTask((QElem*)gTMTaskPtr, delay);
	}
}

#endif

