
/*
 * 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 "SkWidget.h"
#include "SkCanvas.h"
#include "SkKey.h"
#include "SkParsePaint.h"
#include "SkSystemEventTypes.h"
#include "SkTextBox.h"

#if 0

#ifdef SK_DEBUG
    static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
    {
        const char* value = dom.findAttr(node, attr);
        if (value)
            SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
    }
#else
    #define assert_no_attr(dom, node, attr)
#endif

#include "SkAnimator.h"
#include "SkTime.h"

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

enum SkinType {
    kPushButton_SkinType,
    kStaticText_SkinType,

    kSkinTypeCount
};

struct SkinSuite {
    SkinSuite();
    ~SkinSuite()
    {
        for (int i = 0; i < kSkinTypeCount; i++)
            delete fAnimators[i];
    }

    SkAnimator*    get(SkinType);

private:
    SkAnimator*    fAnimators[kSkinTypeCount];
};

SkinSuite::SkinSuite()
{
    static const char kSkinPath[] = "skins/";

    static const char* gSkinNames[] = {
        "pushbutton_skin.xml",
        "statictext_skin.xml"
    };

    for (unsigned i = 0; i < SK_ARRAY_COUNT(gSkinNames); i++)
    {
        size_t        len = strlen(gSkinNames[i]);
        SkString    path(sizeof(kSkinPath) - 1 + len);

        memcpy(path.writable_str(), kSkinPath, sizeof(kSkinPath) - 1);
        memcpy(path.writable_str() + sizeof(kSkinPath) - 1, gSkinNames[i], len);

        fAnimators[i] = new SkAnimator;
        if (!fAnimators[i]->decodeURI(path.c_str()))
        {
            delete fAnimators[i];
            fAnimators[i] = NULL;
        }
    }
}

SkAnimator* SkinSuite::get(SkinType st)
{
    SkASSERT((unsigned)st < kSkinTypeCount);
    return fAnimators[st];
}

static SkinSuite* gSkinSuite;

static SkAnimator* get_skin_animator(SkinType st)
{
#if 0
    if (gSkinSuite == NULL)
        gSkinSuite = new SkinSuite;
    return gSkinSuite->get(st);
#else
    return NULL;
#endif
}

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

void SkWidget::Init()
{
}

void SkWidget::Term()
{
    delete gSkinSuite;
}

void SkWidget::onEnabledChange()
{
    this->inval(NULL);
}

void SkWidget::postWidgetEvent()
{
    if (!fEvent.isType("") && this->hasListeners())
    {
        this->prepareWidgetEvent(&fEvent);
        this->postToListeners(fEvent);
    }
}

void SkWidget::prepareWidgetEvent(SkEvent*)
{
    // override in subclass to add any additional fields before posting
}

void SkWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
    this->INHERITED::onInflate(dom, node);

    if ((node = dom.getFirstChild(node, "event")) != NULL)
        fEvent.inflate(dom, node);
}

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

size_t SkHasLabelWidget::getLabel(SkString* str) const
{
    if (str)
        *str = fLabel;
    return fLabel.size();
}

size_t SkHasLabelWidget::getLabel(char buffer[]) const
{
    if (buffer)
        memcpy(buffer, fLabel.c_str(), fLabel.size());
    return fLabel.size();
}

void SkHasLabelWidget::setLabel(const SkString& str)
{
    this->setLabel(str.c_str(), str.size());
}

void SkHasLabelWidget::setLabel(const char label[])
{
    this->setLabel(label, strlen(label));
}

void SkHasLabelWidget::setLabel(const char label[], size_t len)
{
    if (!fLabel.equals(label, len))
    {
        fLabel.set(label, len);
        this->onLabelChange();
    }
}

void SkHasLabelWidget::onLabelChange()
{
    // override in subclass
}

void SkHasLabelWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
    this->INHERITED::onInflate(dom, node);

    const char* text = dom.findAttr(node, "label");
    if (text)
        this->setLabel(text);
}

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

void SkButtonWidget::setButtonState(State state)
{
    if (fState != state)
    {
        fState = state;
        this->onButtonStateChange();
    }
}

void SkButtonWidget::onButtonStateChange()
{
    this->inval(NULL);
}

void SkButtonWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
    this->INHERITED::onInflate(dom, node);

    int    index;
    if ((index = dom.findList(node, "buttonState", "off,on,unknown")) >= 0)
        this->setButtonState((State)index);
}

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

bool SkPushButtonWidget::onEvent(const SkEvent& evt)
{
    if (evt.isType(SK_EventType_Key) && evt.getFast32() == kOK_SkKey)
    {
        this->postWidgetEvent();
        return true;
    }
    return this->INHERITED::onEvent(evt);
}

static const char* computeAnimatorState(int enabled, int focused, SkButtonWidget::State state)
{
    if (!enabled)
        return "disabled";
    if (state == SkButtonWidget::kOn_State)
    {
        SkASSERT(focused);
        return "enabled-pressed";
    }
    if (focused)
        return "enabled-focused";
    return "enabled";
}

#include "SkBlurMaskFilter.h"
#include "SkEmbossMaskFilter.h"

static void create_emboss(SkPaint* paint, SkScalar radius, bool focus, bool pressed)
{
    SkEmbossMaskFilter::Light    light;

    light.fDirection[0] = SK_Scalar1/2;
    light.fDirection[1] = SK_Scalar1/2;
    light.fDirection[2] = SK_Scalar1/3;
    light.fAmbient        = 0x48;
    light.fSpecular        = 0x80;

    if (pressed)
    {
        light.fDirection[0] = -light.fDirection[0];
        light.fDirection[1] = -light.fDirection[1];
    }
    if (focus)
        light.fDirection[2] += SK_Scalar1/4;

    paint->setMaskFilter(new SkEmbossMaskFilter(light, radius))->unref();
}

void SkPushButtonWidget::onDraw(SkCanvas* canvas)
{
    this->INHERITED::onDraw(canvas);

    SkString label;
    this->getLabel(&label);

    SkAnimator* anim = get_skin_animator(kPushButton_SkinType);

    if (anim)
    {
        SkEvent    evt("user");

        evt.setString("id", "prime");
        evt.setScalar("prime-width", this->width());
        evt.setScalar("prime-height", this->height());
        evt.setString("prime-text", label);
        evt.setString("prime-state", computeAnimatorState(this->isEnabled(), this->hasFocus(), this->getButtonState()));

        (void)anim->doUserEvent(evt);
        SkPaint paint;
        anim->draw(canvas, &paint, SkTime::GetMSecs());
    }
    else
    {
        SkRect    r;
        SkPaint    p;

        r.set(0, 0, this->width(), this->height());
        p.setAntiAliasOn(true);
        p.setColor(SK_ColorBLUE);
        create_emboss(&p, SkIntToScalar(12)/5, this->hasFocus(), this->getButtonState() == kOn_State);
        canvas->drawRoundRect(r, SkScalarHalf(this->height()), SkScalarHalf(this->height()), p);
        p.setMaskFilter(NULL);

        p.setTextAlign(SkPaint::kCenter_Align);

        SkTextBox    box;
        box.setMode(SkTextBox::kOneLine_Mode);
        box.setSpacingAlign(SkTextBox::kCenter_SpacingAlign);
        box.setBox(0, 0, this->width(), this->height());

//        if (this->getButtonState() == kOn_State)
//            p.setColor(SK_ColorRED);
//        else
            p.setColor(SK_ColorWHITE);

        box.draw(canvas, label.c_str(), label.size(), p);
    }
}

SkView::Click* SkPushButtonWidget::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi)
{
    this->acceptFocus();
    return new Click(this);
}

bool SkPushButtonWidget::onClick(Click* click)
{
    SkRect    r;
    State    state = kOff_State;

    this->getLocalBounds(&r);
    if (r.contains(click->fCurr))
    {
        if (click->fState == Click::kUp_State)
            this->postWidgetEvent();
        else
            state = kOn_State;
    }
    this->setButtonState(state);
    return true;
}

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

SkStaticTextView::SkStaticTextView(U32 flags) : SkView(flags)
{
    fMargin.set(0, 0);
    fMode = kFixedSize_Mode;
    fSpacingAlign = SkTextBox::kStart_SpacingAlign;
}

SkStaticTextView::~SkStaticTextView()
{
}

void SkStaticTextView::computeSize()
{
    if (fMode == kAutoWidth_Mode)
    {
        SkScalar width = fPaint.measureText(fText.c_str(), fText.size(), NULL, NULL);
        this->setWidth(width + fMargin.fX * 2);
    }
    else if (fMode == kAutoHeight_Mode)
    {
        SkScalar width = this->width() - fMargin.fX * 2;
        int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0;

        SkScalar    before, after;
        (void)fPaint.measureText(0, NULL, &before, &after);

        this->setHeight(lines * (after - before) + fMargin.fY * 2);
    }
}

void SkStaticTextView::setMode(Mode mode)
{
    SkASSERT((unsigned)mode < kModeCount);

    if (fMode != mode)
    {
        fMode = SkToU8(mode);
        this->computeSize();
    }
}

void SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align)
{
    fSpacingAlign = SkToU8(align);
    this->inval(NULL);
}

void SkStaticTextView::getMargin(SkPoint* margin) const
{
    if (margin)
        *margin = fMargin;
}

void SkStaticTextView::setMargin(SkScalar dx, SkScalar dy)
{
    if (fMargin.fX != dx || fMargin.fY != dy)
    {
        fMargin.set(dx, dy);
        this->computeSize();
        this->inval(NULL);
    }
}

size_t SkStaticTextView::getText(SkString* text) const
{
    if (text)
        *text = fText;
    return fText.size();
}

size_t SkStaticTextView::getText(char text[]) const
{
    if (text)
        memcpy(text, fText.c_str(), fText.size());
    return fText.size();
}

void SkStaticTextView::setText(const SkString& text)
{
    this->setText(text.c_str(), text.size());
}

void SkStaticTextView::setText(const char text[])
{
    this->setText(text, strlen(text));
}

void SkStaticTextView::setText(const char text[], size_t len)
{
    if (!fText.equals(text, len))
    {
        fText.set(text, len);
        this->computeSize();
        this->inval(NULL);
    }
}

void SkStaticTextView::getPaint(SkPaint* paint) const
{
    if (paint)
        *paint = fPaint;
}

void SkStaticTextView::setPaint(const SkPaint& paint)
{
    if (fPaint != paint)
    {
        fPaint = paint;
        this->computeSize();
        this->inval(NULL);
    }
}

void SkStaticTextView::onDraw(SkCanvas* canvas)
{
    this->INHERITED::onDraw(canvas);

    if (fText.isEmpty())
        return;

    SkTextBox    box;

    box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode);
    box.setSpacingAlign(this->getSpacingAlign());
    box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY);
    box.draw(canvas, fText.c_str(), fText.size(), fPaint);
}

void SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
    this->INHERITED::onInflate(dom, node);

    int    index;
    if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0)
        this->setMode((Mode)index);
    else
        assert_no_attr(dom, node, "mode");

    if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0)
        this->setSpacingAlign((SkTextBox::SpacingAlign)index);
    else
        assert_no_attr(dom, node, "mode");

    SkScalar s[2];
    if (dom.findScalars(node, "margin", s, 2))
        this->setMargin(s[0], s[1]);
    else
        assert_no_attr(dom, node, "margin");

    const char* text = dom.findAttr(node, "text");
    if (text)
        this->setText(text);

    if ((node = dom.getFirstChild(node, "paint")) != NULL)
        SkPaint_Inflate(&fPaint, dom, node);
}

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

#include "SkImageDecoder.h"

SkBitmapView::SkBitmapView(U32 flags) : SkView(flags)
{
}

SkBitmapView::~SkBitmapView()
{
}

bool SkBitmapView::getBitmap(SkBitmap* bitmap) const
{
    if (bitmap)
        *bitmap = fBitmap;
    return fBitmap.getConfig() != SkBitmap::kNo_Config;
}

void SkBitmapView::setBitmap(const SkBitmap* bitmap, bool viewOwnsPixels)
{
    if (bitmap)
    {
        fBitmap = *bitmap;
        fBitmap.setOwnsPixels(viewOwnsPixels);
    }
}

bool SkBitmapView::loadBitmapFromFile(const char path[])
{
    SkBitmap    bitmap;

    if (SkImageDecoder::DecodeFile(path, &bitmap))
    {
        this->setBitmap(&bitmap, true);
        bitmap.setOwnsPixels(false);
        return true;
    }
    return false;
}

void SkBitmapView::onDraw(SkCanvas* canvas)
{
    if (fBitmap.getConfig() != SkBitmap::kNo_Config &&
        fBitmap.width() && fBitmap.height())
    {
        SkAutoCanvasRestore    restore(canvas, true);
        SkPaint                p;

        p.setFilterType(SkPaint::kBilinear_FilterType);
        canvas->scale(    this->width() / fBitmap.width(),
                        this->height() / fBitmap.height(),
                        0, 0);
        canvas->drawBitmap(fBitmap, 0, 0, p);
    }
}

void SkBitmapView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
    this->INHERITED::onInflate(dom, node);

    const char* src = dom.findAttr(node, "src");
    if (src)
        (void)this->loadBitmapFromFile(src);
}

#endif
