
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkWindow.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkOSMenu.h"
#include "SkSystemEventTypes.h"
#include "SkTime.h"

#define SK_EventDelayInval "\xd" "n" "\xa" "l"

#define TEST_BOUNDERx

#include "SkBounder.h"
class test_bounder : public SkBounder {
public:
    test_bounder(const SkBitmap& bm) : fCanvas(bm) {}
protected:
    virtual bool onIRect(const SkIRect& r)
    {
        SkRect    rr;

        rr.set(SkIntToScalar(r.fLeft), SkIntToScalar(r.fTop),
                SkIntToScalar(r.fRight), SkIntToScalar(r.fBottom));

        SkPaint    p;

        p.setStyle(SkPaint::kStroke_Style);
        p.setColor(SK_ColorYELLOW);

#if 0
        rr.inset(SK_ScalarHalf, SK_ScalarHalf);
#else
        rr.inset(-SK_ScalarHalf, -SK_ScalarHalf);
#endif

        fCanvas.drawRect(rr, p);
        return true;
    }
private:
    SkCanvas    fCanvas;
};

SkWindow::SkWindow() : fFocusView(NULL)
{
    fClicks.reset();
    fWaitingOnInval = false;

#ifdef SK_BUILD_FOR_WINCE
    fConfig = SkBitmap::kRGB_565_Config;
#else
    fConfig = SkBitmap::kARGB_8888_Config;
#endif

    fMatrix.reset();
}

SkWindow::~SkWindow()
{
    fClicks.deleteAll();
    fMenus.deleteAll();
}

SkCanvas* SkWindow::createCanvas() {
    return new SkCanvas(this->getBitmap());
}

void SkWindow::setMatrix(const SkMatrix& matrix) {
    if (fMatrix != matrix) {
        fMatrix = matrix;
        this->inval(NULL);
    }
}

void SkWindow::preConcat(const SkMatrix& matrix) {
    SkMatrix m;
    m.setConcat(fMatrix, matrix);
    this->setMatrix(m);
}

void SkWindow::postConcat(const SkMatrix& matrix) {
    SkMatrix m;
    m.setConcat(matrix, fMatrix);
    this->setMatrix(m);
}

void SkWindow::setConfig(SkBitmap::Config config)
{
    this->resize(fBitmap.width(), fBitmap.height(), config);
}

void SkWindow::resize(int width, int height, SkBitmap::Config config)
{
    if (config == SkBitmap::kNo_Config)
        config = fConfig;

    if (width != fBitmap.width() || height != fBitmap.height() || config != fConfig)
    {
        fConfig = config;
        fBitmap.setConfig(config, width, height, 0, kOpaque_SkAlphaType);
        fBitmap.allocPixels();

        this->setSize(SkIntToScalar(width), SkIntToScalar(height));
        this->inval(NULL);
    }
}

void SkWindow::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
{
    fBitmap.eraseARGB(a, r, g, b);
}

void SkWindow::eraseRGB(U8CPU r, U8CPU g, U8CPU b)
{
    fBitmap.eraseARGB(0xFF, r, g, b);
}

bool SkWindow::handleInval(const SkRect* localR)
{
    SkIRect    ir;

    if (localR) {
        SkRect devR;
        SkMatrix inverse;
        if (!fMatrix.invert(&inverse)) {
            return false;
        }
        fMatrix.mapRect(&devR, *localR);
        devR.round(&ir);
    } else {
        ir.set(0, 0,
               SkScalarRound(this->width()),
               SkScalarRound(this->height()));
    }
    fDirtyRgn.op(ir, SkRegion::kUnion_Op);

    this->onHandleInval(ir);
    return true;
}

void SkWindow::forceInvalAll() {
    fDirtyRgn.setRect(0, 0,
                      SkScalarCeil(this->width()),
                      SkScalarCeil(this->height()));
}

#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
    #include <windows.h>
    #include <gx.h>
    extern GXDisplayProperties gDisplayProps;
#endif

#ifdef SK_SIMULATE_FAILED_MALLOC
extern bool gEnableControlledThrow;
#endif

bool SkWindow::update(SkIRect* updateArea)
{
    if (!fDirtyRgn.isEmpty())
    {
        SkBitmap bm = this->getBitmap();

#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
        char* buffer = (char*)GXBeginDraw();
        SkASSERT(buffer);

        RECT    rect;
        GetWindowRect((HWND)((SkOSWindow*)this)->getHWND(), &rect);
        buffer += rect.top * gDisplayProps.cbyPitch + rect.left * gDisplayProps.cbxPitch;

        bm.setPixels(buffer);
#endif

        SkAutoTUnref<SkCanvas> canvas(this->createCanvas());

        canvas->clipRegion(fDirtyRgn);
        if (updateArea)
            *updateArea = fDirtyRgn.getBounds();

        SkAutoCanvasRestore acr(canvas, true);
        canvas->concat(fMatrix);

        // empty this now, so we can correctly record any inval calls that
        // might be made during the draw call.
        fDirtyRgn.setEmpty();

#ifdef TEST_BOUNDER
        test_bounder    b(bm);
        canvas->setBounder(&b);
#endif
#ifdef SK_SIMULATE_FAILED_MALLOC
        gEnableControlledThrow = true;
#endif
#ifdef SK_BUILD_FOR_WIN32
        //try {
            this->draw(canvas);
        //}
        //catch (...) {
        //}
#else
        this->draw(canvas);
#endif
#ifdef SK_SIMULATE_FAILED_MALLOC
        gEnableControlledThrow = false;
#endif
#ifdef TEST_BOUNDER
        canvas->setBounder(NULL);
#endif

#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
        GXEndDraw();
#endif

        return true;
    }
    return false;
}

bool SkWindow::handleChar(SkUnichar uni)
{
    if (this->onHandleChar(uni))
        return true;

    SkView* focus = this->getFocusView();
    if (focus == NULL)
        focus = this;

    SkEvent evt(SK_EventType_Unichar);
    evt.setFast32(uni);
    return focus->doEvent(evt);
}

bool SkWindow::handleKey(SkKey key)
{
    if (key == kNONE_SkKey)
        return false;

    if (this->onHandleKey(key))
        return true;

    // send an event to the focus-view
    {
        SkView* focus = this->getFocusView();
        if (focus == NULL)
            focus = this;

        SkEvent evt(SK_EventType_Key);
        evt.setFast32(key);
        if (focus->doEvent(evt))
            return true;
    }

    if (key == kUp_SkKey || key == kDown_SkKey)
    {
        if (this->moveFocus(key == kUp_SkKey ? kPrev_FocusDirection : kNext_FocusDirection) == NULL)
            this->onSetFocusView(NULL);
        return true;
    }
    return false;
}

bool SkWindow::handleKeyUp(SkKey key)
{
    if (key == kNONE_SkKey)
        return false;

    if (this->onHandleKeyUp(key))
        return true;

    //send an event to the focus-view
    {
        SkView* focus = this->getFocusView();
        if (focus == NULL)
            focus = this;

        //should this one be the same?
        SkEvent evt(SK_EventType_KeyUp);
        evt.setFast32(key);
        if (focus->doEvent(evt))
            return true;
    }
    return false;
}

void SkWindow::addMenu(SkOSMenu* menu) {
    *fMenus.append() = menu;
    this->onAddMenu(menu);
}

void SkWindow::setTitle(const char title[]) {
    if (NULL == title) {
        title = "";
    }
    fTitle.set(title);
    this->onSetTitle(title);
}

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

bool SkWindow::onEvent(const SkEvent& evt)
{
    if (evt.isType(SK_EventDelayInval))
    {
        SkRegion::Iterator    iter(fDirtyRgn);

        for (; !iter.done(); iter.next())
            this->onHandleInval(iter.rect());
        fWaitingOnInval = false;
        return true;
    }
    return this->INHERITED::onEvent(evt);
}

bool SkWindow::onGetFocusView(SkView** focus) const
{
    if (focus)
        *focus = fFocusView;
    return true;
}

bool SkWindow::onSetFocusView(SkView* focus)
{
    if (fFocusView != focus)
    {
        if (fFocusView)
            fFocusView->onFocusChange(false);
        fFocusView = focus;
        if (focus)
            focus->onFocusChange(true);
    }
    return true;
}

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

void SkWindow::onHandleInval(const SkIRect&)
{
}

bool SkWindow::onHandleChar(SkUnichar)
{
    return false;
}

bool SkWindow::onHandleKey(SkKey)
{
    return false;
}

bool SkWindow::onHandleKeyUp(SkKey)
{
    return false;
}

bool SkWindow::handleClick(int x, int y, Click::State state, void *owner,
                           unsigned modifierKeys) {
    return this->onDispatchClick(x, y, state, owner, modifierKeys);
}

bool SkWindow::onDispatchClick(int x, int y, Click::State state,
                               void* owner, unsigned modifierKeys) {
    bool handled = false;

    // First, attempt to find an existing click with this owner.
    int index = -1;
    for (int i = 0; i < fClicks.count(); i++) {
        if (owner == fClicks[i]->fOwner) {
            index = i;
            break;
        }
    }

    switch (state) {
        case Click::kDown_State: {
            if (index != -1) {
                delete fClicks[index];
                fClicks.remove(index);
            }
            Click* click = this->findClickHandler(SkIntToScalar(x),
                                                  SkIntToScalar(y), modifierKeys);

            if (click) {
                click->fOwner = owner;
                *fClicks.append() = click;
                SkView::DoClickDown(click, x, y, modifierKeys);
                handled = true;
            }
            break;
        }
        case Click::kMoved_State:
            if (index != -1) {
                SkView::DoClickMoved(fClicks[index], x, y, modifierKeys);
                handled = true;
            }
            break;
        case Click::kUp_State:
            if (index != -1) {
                SkView::DoClickUp(fClicks[index], x, y, modifierKeys);
                delete fClicks[index];
                fClicks.remove(index);
                handled = true;
            }
            break;
        default:
            // Do nothing
            break;
    }
    return handled;
}
