
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkDisplayEvents.h"
#include "SkAnimateMaker.h"
#include "SkAnimator.h"
#include "SkDisplayEvent.h"
#include "SkDisplayMovie.h"
#include "SkDrawable.h"
#ifdef SK_DEBUG
#include "SkDump.h"
#endif

SkEventState::SkEventState() : fCode(0), fDisable(false), fDisplayable(0), fX(0), fY(0) {
}

SkEvents::SkEvents() {
}

SkEvents::~SkEvents() {
}

bool SkEvents::doEvent(SkAnimateMaker& maker, SkDisplayEvent::Kind kind, SkEventState* state) {
/*#ifdef SK_DUMP_ENABLED
    if (maker.fDumpEvents) {
        SkDebugf("doEvent: ");
        SkString str;
        SkDump::GetEnumString(SkType_EventKind, kind, &str);
        SkDebugf("kind=%s ", str.c_str());
        if (state && state->fDisplayable)
            state->fDisplayable->SkDisplayable::dump(&maker);
        else
            SkDebugf("\n");
    }
#endif*/
    bool handled = false;
    SkDisplayable** firstMovie = maker.fMovies.begin();
    SkDisplayable** endMovie = maker.fMovies.end();
    for (SkDisplayable** ptr = firstMovie; ptr < endMovie; ptr++) {
        SkDisplayMovie* movie = (SkDisplayMovie*) *ptr;
        if (kind != SkDisplayEvent::kOnload)
            movie->doEvent(kind, state);
    }
    SkDisplayable* displayable = state ? state->fDisplayable : NULL;
    int keyCode = state ? state->fCode : 0;
    int count = fEvents.count();
    for (int index = 0; index < count; index++) {
        SkDisplayEvent* evt = fEvents[index];
        if (evt->disable)
            continue;
        if (evt->kind != kind)
            continue;
        if (evt->code != (SkKey) -1) {
            if ((int) evt->code > keyCode || (int) (evt->fMax != (SkKey) -1 ? evt->fMax : evt->code) < keyCode)
                continue;
            evt->fLastCode = (SkKey) keyCode;
        }
        if (evt->fTarget != NULL && evt->fTarget != displayable)
            continue;
        if (state == NULL || state->fDisable == 0) {
            if (kind >= SkDisplayEvent::kMouseDown && kind <= SkDisplayEvent::kMouseUp) {
                evt->x = state->fX;
                evt->y = state->fY;
            }
            if (evt->enableEvent(maker))
                fError = true;
        }
        handled = true;
    }
    return handled;
}

#ifdef SK_DUMP_ENABLED
void SkEvents::dump(SkAnimateMaker& maker) {
    int index;
    SkTDDrawableArray& drawArray = maker.fDisplayList.fDrawList;
    int count = drawArray.count();
    for (index = 0; index < count; index++) {
        SkDrawable* drawable = drawArray[index];
        drawable->dumpEvents(); 
    }
    count = fEvents.count();
    for (index = 0; index < count; index++) {
        SkDisplayEvent* evt = fEvents[index];
        evt->dumpEvent(&maker);
    }
}
#endif

// currently this only removes onLoad events
void SkEvents::removeEvent(SkDisplayEvent::Kind kind, SkEventState* state) {
    int keyCode = state ? state->fCode : 0;
    SkDisplayable* displayable = state ? state->fDisplayable : NULL;
    for (SkDisplayEvent** evtPtr = fEvents.begin(); evtPtr < fEvents.end(); evtPtr++) {
        SkDisplayEvent* evt = *evtPtr;
        if (evt->kind != kind)
            continue;
        if (evt->code != (SkKey) -1) {
            if ((int) evt->code > keyCode || (int) (evt->fMax != (SkKey) -1 ? evt->fMax : evt->code) < keyCode)
                continue;
        }
        if (evt->fTarget != NULL && evt->fTarget != displayable)
            continue;
        int index = fEvents.find(evt);
        fEvents.remove(index);
    }
}
