/*
 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SKY_ENGINE_CORE_HTML_TEXTMETRICS_H_
#define SKY_ENGINE_CORE_HTML_TEXTMETRICS_H_

#include "sky/engine/bindings/core/v8/ScriptWrappable.h"
#include "sky/engine/platform/heap/Handle.h"
#include "sky/engine/wtf/PassRefPtr.h"
#include "sky/engine/wtf/RefCounted.h"

namespace blink {

class TextMetrics final : public RefCounted<TextMetrics>, public ScriptWrappable {
    DEFINE_WRAPPERTYPEINFO();
public:
    static PassRefPtr<TextMetrics> create() { return adoptRef(new TextMetrics); }

    float width() const { return m_width; }
    void setWidth(float w) { m_width = w; }

    float actualBoundingBoxLeft() const { return m_actualBoundingBoxLeft; }
    void setActualBoundingBoxLeft(float actualBoundingBoxLeft) { m_actualBoundingBoxLeft = actualBoundingBoxLeft; }

    float actualBoundingBoxRight() const { return m_actualBoundingBoxRight; }
    void setActualBoundingBoxRight(float actualBoundingBoxRight) { m_actualBoundingBoxRight = actualBoundingBoxRight; }

    float fontBoundingBoxAscent() const { return m_fontBoundingBoxAscent; }
    void setFontBoundingBoxAscent(float fontBoundingBoxAscent) { m_fontBoundingBoxAscent = fontBoundingBoxAscent; }

    float fontBoundingBoxDescent() const { return m_fontBoundingBoxDescent; }
    void setFontBoundingBoxDescent(float fontBoundingBoxDescent) { m_fontBoundingBoxDescent = fontBoundingBoxDescent; }

    float actualBoundingBoxAscent() const { return m_actualBoundingBoxAscent; }
    void setActualBoundingBoxAscent(float actualBoundingBoxAscent) { m_actualBoundingBoxAscent = actualBoundingBoxAscent; }

    float actualBoundingBoxDescent() const { return m_actualBoundingBoxDescent; }
    void setActualBoundingBoxDescent(float actualBoundingBoxDescent) { m_actualBoundingBoxDescent = actualBoundingBoxDescent; }

    float emHeightAscent() const { return m_emHeightAscent; }
    void setEmHeightAscent(float emHeightAscent) { m_emHeightAscent = emHeightAscent; }

    float emHeightDescent() const { return m_emHeightDescent; }
    void setEmHeightDescent(float emHeightDescent) { m_emHeightDescent = emHeightDescent; }

    float hangingBaseline() const { return m_hangingBaseline; }
    void setHangingBaseline(float hangingBaseline) { m_hangingBaseline = hangingBaseline; }

    float alphabeticBaseline() const { return m_alphabeticBaseline; }
    void setAlphabeticBaseline(float alphabeticBaseline) { m_alphabeticBaseline = alphabeticBaseline; }

    float ideographicBaseline() const { return m_ideographicBaseline; }
    void setIdeographicBaseline(float ideographicBaseline) { m_ideographicBaseline = ideographicBaseline; }

private:
    TextMetrics()
        : m_width(0)
        , m_actualBoundingBoxLeft(0)
        , m_actualBoundingBoxRight(0)
        , m_fontBoundingBoxAscent(0)
        , m_fontBoundingBoxDescent(0)
        , m_actualBoundingBoxAscent(0)
        , m_actualBoundingBoxDescent(0)
        , m_emHeightAscent(0)
        , m_emHeightDescent(0)
        , m_hangingBaseline(0)
        , m_alphabeticBaseline(0)
        , m_ideographicBaseline(0)
    {
    }

    // x-direction
    float m_width;
    float m_actualBoundingBoxLeft;
    float m_actualBoundingBoxRight;

    // y-direction
    float m_fontBoundingBoxAscent;
    float m_fontBoundingBoxDescent;
    float m_actualBoundingBoxAscent;
    float m_actualBoundingBoxDescent;
    float m_emHeightAscent;
    float m_emHeightDescent;
    float m_hangingBaseline;
    float m_alphabeticBaseline;
    float m_ideographicBaseline;
};

} // namespace blink

#endif  // SKY_ENGINE_CORE_HTML_TEXTMETRICS_H_
