/*
 * 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 "OverView.h"
#include "SampleCode.h"
#include "SkCanvas.h"
#include "SkView.h"

static const char gIsOverview[] = "is-overview";

static int to_lower(int c) {
    if ('A' <= c && c <= 'Z') {
        c = c - 'A' + 'a';
    }
    return c;
}

static void make_lc(SkString* str) {
    char* ptr = str->writable_str();
    while (*ptr) {
        *ptr = to_lower(*ptr);
        ptr += 1;
    }
}

static bool case_insensitive_find(const SkString& base, const SkString& sub) {
    SkString lcBase(base);
    SkString lcSub(sub);
    make_lc(&lcBase);
    make_lc(&lcSub);
    return lcBase.find(lcSub.c_str()) >= 0;
}

static bool draw_this_name(const SkString& name, const SkString& filter) {
    if (filter.isEmpty()) {
        return true;
    }
    return case_insensitive_find(name, filter);
}

class OverView : public SkView {
public:
    OverView(int count, const SkViewFactory* factories[]);
    ~OverView() override;

protected:
    bool onEvent(const SkEvent&) override;
    bool onQuery(SkEvent* evt) override {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Overview");
            return true;
        }
        if (evt->isType(gIsOverview)) {
            return true;
        }
        SkUnichar uni;
        if (SampleCode::CharQ(*evt, &uni)) {
            if (uni >= ' ') {
                fMatchStr.appendUnichar(uni);
            }
            this->inval(nullptr);
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    void onDraw(SkCanvas* canvas) override;

    bool onSendClickToChildren(SkScalar x, SkScalar y, unsigned modi) override {
        return false;
    }

    Click* onFindClickHandler(SkScalar cx, SkScalar cy, unsigned modi) override {
        const SkRect crect = SkRect::MakeXYWH(cx - 0.5f, cy - 0.5f, 1, 1);
        SkPoint loc = this->start();
        for (int i = 0; i < fCount; ++i) {
            if (draw_this_name(fNames[i], fMatchStr)) {
                if (this->bounds(loc).intersects(crect)) {
                    SkEvent evt("set-curr-index");
                    evt.setFast32(i);
                    this->sendEventToParents(evt);
                    break;
                }
                this->next(&loc);
            }
        }
        return nullptr;
    }

private:
    int fCount;
    const SkViewFactory** fFactories;
    SkString* fNames;
    SkString fMatchStr;
    SkPaint fNamePaint;
    SkPaint::FontMetrics fNameMetrics;
    SkScalar fNameW;
    SkScalar fNameH;

    SkRect bounds(const SkPoint& loc) const {
        return SkRect::MakeXYWH(loc.x(), loc.y() + fNameMetrics.fAscent, fNameW, fNameH);
    }

    SkPoint start() const {
        return SkPoint::Make(10, -fNameMetrics.fTop);
    }

    void next(SkPoint* loc) const {
        loc->fY += fNameH;
        if (loc->fY > this->height() - fNameMetrics.fBottom) {
            loc->fY = -fNameMetrics.fTop;
            loc->fX += fNameW;
        }
    }

    typedef SkView INHERITED;
};

SkView* create_overview(int count, const SkViewFactory* factories[]) {
    return new OverView(count, factories);
}

bool is_overview(SkView* view) {
    SkEvent isOverview(gIsOverview);
    return view->doQuery(&isOverview);
}

OverView::OverView(int count, const SkViewFactory* factories[]) {
    fCount = count;
    fFactories = factories;

    fNames = new SkString[count];
    for (int i = 0; i < count; ++i) {
        SkView* view = (*fFactories[i])();
        if (view) {
            (void)SampleCode::RequestTitle(view, &fNames[i]);
            if (0 == fNames[i].find("GM:")) {
                fNames[i].remove(0, 3);
            }
        }
    }

    fNamePaint.setAntiAlias(true);
    fNamePaint.setTextSize(12);
    fNameW = 160;
    fNameH = fNamePaint.getFontMetrics(&fNameMetrics);
}

OverView::~OverView() {
    delete[] fNames;
}

bool OverView::onEvent(const SkEvent& evt) {
    return this->INHERITED::onEvent(evt);
}

void OverView::onDraw(SkCanvas* canvas) {
    SkPaint paint;
    paint.setColor(0xFFF8F8F8);
    canvas->drawPaint(paint);

    SkPoint loc = this->start();
    for (int i = 0; i < fCount; ++i) {
        if (draw_this_name(fNames[i], fMatchStr)) {
            canvas->drawRect(this->bounds(loc), paint);
            canvas->drawString(fNames[i], loc.x(), loc.y(), fNamePaint);
            this->next(&loc);
        }
    }
}
