
/*
 * 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 "SkOSWindow_SDL.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
#include "SkGLCanvas.h"
#include "SkOSMenu.h"
#include "SkTime.h"

static void post_SkEvent_event() {
    SDL_Event evt;
    evt.type = SDL_USEREVENT;
    evt.user.type = SDL_USEREVENT;
    evt.user.code = 0;
    evt.user.data1 = NULL;
    evt.user.data2 = NULL;
    SDL_PushEvent(&evt);
}

static bool skia_setBitmapFromSurface(SkBitmap* dst, SDL_Surface* src) {
    SkBitmap::Config config;

    switch (src->format->BytesPerPixel) {
        case 2:
            config = SkBitmap::kRGB_565_Config;
            break;
        case 4:
            config = SkBitmap::kARGB_8888_Config;
            break;
        default:
            return false;
    }

    dst->setConfig(config, src->w, src->h, src->pitch);
    dst->setPixels(src->pixels);
    return true;
}

SkOSWindow::SkOSWindow(void* screen) {
    fScreen = reinterpret_cast<SDL_Surface*>(screen);
    this->resize(fScreen->w, fScreen->h);

    uint32_t rmask = SK_R32_MASK << SK_R32_SHIFT;
    uint32_t gmask = SK_G32_MASK << SK_G32_SHIFT;
    uint32_t bmask = SK_B32_MASK << SK_B32_SHIFT;
    uint32_t amask = SK_A32_MASK << SK_A32_SHIFT;

    if (fScreen->flags & SDL_OPENGL) {
        fSurface = NULL;
        fGLCanvas = new SkGLCanvas;
        fGLCanvas->setViewport(fScreen->w, fScreen->h);
    } else {
        fGLCanvas = NULL;
        fSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, fScreen->w, fScreen->h,
                                        32, rmask, gmask, bmask, amask);
    }
}

SkOSWindow::~SkOSWindow() {
    delete fGLCanvas;
    if (fSurface) {
        SDL_FreeSurface(fSurface);
    }
}

#include <OpenGL/gl.h>

void SkOSWindow::doDraw() {
    if (fGLCanvas) {
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
        glEnable(GL_TEXTURE_2D);
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);

        int count = fGLCanvas->save();
        this->draw(fGLCanvas);
        fGLCanvas->restoreToCount(count);
        SDL_GL_SwapBuffers( );
    } else {
        if ( SDL_MUSTLOCK(fSurface) ) {
            if ( SDL_LockSurface(fSurface) < 0 ) {
                return;
            }
        }

        SkBitmap bitmap;

        if (skia_setBitmapFromSurface(&bitmap, fSurface)) {
            SkCanvas canvas(bitmap);
            this->draw(&canvas);
        }

        if ( SDL_MUSTLOCK(fSurface) ) {
            SDL_UnlockSurface(fSurface);
        }

        int result = SDL_BlitSurface(fSurface, NULL, fScreen, NULL);
        if (result) {
            SkDebugf("------- SDL_BlitSurface returned %d\n", result);
        }
        SDL_UpdateRect(fScreen, 0, 0, fScreen->w, fScreen->h);
    }
}

static SkKey find_skkey(SDLKey src) {
    // this array must match the enum order in SkKey.h
    static const SDLKey gKeys[] = {
        SDLK_UNKNOWN,
        SDLK_UNKNOWN,   // left softkey
        SDLK_UNKNOWN,   // right softkey
        SDLK_UNKNOWN,   // home
        SDLK_UNKNOWN,   // back
        SDLK_UNKNOWN,   // send
        SDLK_UNKNOWN,   // end
        SDLK_0,
        SDLK_1,
        SDLK_2,
        SDLK_3,
        SDLK_4,
        SDLK_5,
        SDLK_6,
        SDLK_7,
        SDLK_8,
        SDLK_9,
        SDLK_ASTERISK,
        SDLK_HASH,
        SDLK_UP,
        SDLK_DOWN,
        SDLK_LEFT,
        SDLK_RIGHT,
        SDLK_RETURN,    // OK
        SDLK_UNKNOWN,   // volume up
        SDLK_UNKNOWN,   // volume down
        SDLK_UNKNOWN,   // power
        SDLK_UNKNOWN,   // camera
    };

    const SDLKey* array = gKeys;
    for (size_t i = 0; i < SK_ARRAY_COUNT(gKeys); i++) {
        if (array[i] == src) {
            return static_cast<SkKey>(i);
        }
    }
    return kNONE_SkKey;
}

void SkOSWindow::handleSDLEvent(const SDL_Event& event) {
    switch (event.type) {
        case SDL_VIDEORESIZE:
            this->resize(event.resize.w, event.resize.h);
            break;
        case SDL_VIDEOEXPOSE:
            this->doDraw();
            break;
        case SDL_MOUSEMOTION:
            if (event.motion.state == SDL_PRESSED) {
                this->handleClick(event.motion.x, event.motion.y,
                                   SkView::Click::kMoved_State);
            }
            break;
        case SDL_MOUSEBUTTONDOWN:
        case SDL_MOUSEBUTTONUP:
            this->handleClick(event.button.x, event.button.y,
                               event.button.state == SDL_PRESSED ?
                               SkView::Click::kDown_State :
                               SkView::Click::kUp_State);
            break;
        case SDL_KEYDOWN: {
            SkKey sk = find_skkey(event.key.keysym.sym);
            if (kNONE_SkKey != sk) {
                if (event.key.state == SDL_PRESSED) {
                    this->handleKey(sk);
                } else {
                    this->handleKeyUp(sk);
                }
            }
            break;
        }
        case SDL_USEREVENT:
            if (SkEvent::ProcessEvent()) {
                post_SkEvent_event();
            }
            break;
    }
}

void SkOSWindow::onHandleInval(const SkIRect& r) {
    SDL_Event evt;
    evt.type = SDL_VIDEOEXPOSE;
    evt.expose.type = SDL_VIDEOEXPOSE;
    SDL_PushEvent(&evt);
}

void SkOSWindow::onSetTitle(const char title[]) {
    SDL_WM_SetCaption(title, NULL);
}

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

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

void SkEvent::SignalNonEmptyQueue() {
    SkDebugf("-------- signal nonempty\n");
    post_SkEvent_event();
}

static Uint32 timer_callback(Uint32 interval) {
//    SkDebugf("-------- timercallback %d\n", interval);
    SkEvent::ServiceQueueTimer();
    return 0;
}

void SkEvent::SignalQueueTimer(SkMSec delay)
{
    SDL_SetTimer(0, NULL);
    if (delay) {
        SDL_SetTimer(delay, timer_callback);
    }
}
