#include "SkTypes.h"

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

#include <AGL/agl.h>

#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), fAGLCtx(NULL)
{
	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,		kEventMouseMoved			},
		{ 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:
                    if (win->handleClick(pt.h, pt.v, Click::kDown_State)) {
                        result = noErr;
                    }
                    break;
                case kEventMouseMoved:
                    // fall through
                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);
	}
}

#define USE_MSAA 0

AGLContext create_gl(WindowRef wref)
{
    GLint major, minor;
    AGLContext ctx;

    aglGetVersion(&major, &minor);
    SkDebugf("---- agl version %d %d\n", major, minor);

    const GLint pixelAttrs[] = {
        AGL_RGBA,
        AGL_STENCIL_SIZE, 8,
#if USE_MSAA
        AGL_SAMPLE_BUFFERS_ARB, 1,
        AGL_MULTISAMPLE,
        AGL_SAMPLES_ARB, 8,
#endif
        AGL_ACCELERATED,
        AGL_DOUBLEBUFFER,
        AGL_NONE
    };
    AGLPixelFormat format = aglChoosePixelFormat(NULL, 0, pixelAttrs);
    //AGLPixelFormat format = aglCreatePixelFormat(pixelAttrs);
    SkDebugf("----- agl format %p\n", format);
    ctx = aglCreateContext(format, NULL);
    SkDebugf("----- agl context %p\n", ctx);
    aglDestroyPixelFormat(format);

    static const GLint interval = 1;
    aglSetInteger(ctx, AGL_SWAP_INTERVAL, &interval);
    aglSetCurrentContext(ctx);
    return ctx;
}

bool SkOSWindow::attachGL()
{
    if (NULL == fAGLCtx) {
        fAGLCtx = create_gl((WindowRef)fHWND);
        if (NULL == fAGLCtx) {
            return false;
        }
    }

    GLboolean success = true;

    int width, height;

    success = aglSetWindowRef((AGLContext)fAGLCtx, (WindowRef)fHWND);
    width = this->width();
    height = this->height();

    GLenum err = aglGetError();
    if (err) {
        SkDebugf("---- aglSetWindowRef %d %d %s [%d %d]\n", success, err,
                 aglErrorString(err), width, height);
    }

    if (success) {
        glViewport(0, 0, width, height);
        glClearColor(0, 0, 0, 0);
        glClearStencil(0);
        glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    }
    return success;
}

void SkOSWindow::detachGL() {
    aglSetWindowRef((AGLContext)fAGLCtx, NULL);
}

void SkOSWindow::presentGL() {
    aglSwapBuffers((AGLContext)fAGLCtx);
}

#endif

