/*
 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup UI_Components
 * @{
 *
 * @brief Defines UI components such as buttons, texts, images, lists, and progress bars.
 *
 * @since 1.0
 * @version 1.0
 */

/**
 * @file ui_label_button.h
 *
 * @brief Declares a label button.
 *
 * @since 1.0
 * @version 1.0
 */

#ifndef GRAPHIC_LITE_UI_LABEL_BUTTON_H
#define GRAPHIC_LITE_UI_LABEL_BUTTON_H

#include "common/text.h"
#include "components/ui_button.h"
#include "gfx_utils/graphic_log.h"

namespace OHOS {
/**
 * @brief Provides the functions related to a label button.
 *
 * @since 1.0
 * @version 1.0
 */
class UILabelButton : public UIButton {
public:
    /**
     * @brief A constructor used to create a <b>UILabelButton</b> instance.
     *
     * @since 1.0
     * @version 1.0
     */
    UILabelButton();

    /**
     * @brief A destructor used to delete the <b>UILabelButton</b> instance.
     *
     * @since 1.0
     * @version 1.0
     */
    virtual ~UILabelButton();

    /**
     * @brief Draws a label button.
     *
     * @since 1.0
     * @version 1.0
     */
    void OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override;

    /**
     * @brief Obtains the view type.
     *
     * @return Returns <b>UI_LABEL_BUTTON</b>, as defined in {@link UIViewType}.
     * @since 1.0
     * @version 1.0
     */
    UIViewType GetViewType() const override
    {
        return UI_LABEL_BUTTON;
    }

    /**
     * @brief Sets the text for this label button.
     *
     * @param text Indicates the pointer to the text.
     * @since 1.0
     * @version 1.0
     */
    void SetText(const char* text)
    {
        InitLabelButtonText();
        labelButtonText_->SetText(text);
#if defined(CONFIG_SCALE_FONT_SIZE) && (CONFIG_SCALE_FONT_SIZE == 1)
        needRefresh_ = labelButtonText_->IsNeedRefresh();
#endif
    }

    /**
     * @brief Obtains the text of this label button.
     *
     * @return Returns the text.
     * @since 1.0
     * @version 1.0
     */
    const char* GetText() const
    {
        return (labelButtonText_ == nullptr) ? nullptr : labelButtonText_->GetText();
    }

    /**
     * @brief Sets the position for this label relative to the button holding it.
     *
     * @param x Indicates the offset distance by which this label is moved on the x-axis.
     * @param y Indicates the offset distance by which this label is moved on the y-axis.
     * @since 1.0
     * @version 1.0
     */
    void SetLabelPosition(int16_t x, int16_t y)
    {
        offset_.x = x;
        offset_.y = y;
    }

    /**
     * @brief Obtains the position of this label relative to the button holding it.
     *
     * @return Returns the position of this label.
     * @since 1.0
     * @version 1.0
     */
    Point GetLabelPosition() const
    {
        return offset_;
    }

    /**
     * @brief Sets the alignment mode for this text.
     *
     * @param align Indicates the text alignment mode to set, as defined in {@link UITextLanguageAlignment}.
     * @since 1.0
     * @version 1.0
     */
    void SetAlign(UITextLanguageAlignment align)
    {
        InitLabelButtonText();
        labelButtonText_->SetAlign(align, TEXT_ALIGNMENT_CENTER);
#if defined(CONFIG_SCALE_FONT_SIZE) && (CONFIG_SCALE_FONT_SIZE == 1)
        needRefresh_ = labelButtonText_->IsNeedRefresh();
#endif
    }

    /**
     * @brief Obtains the alignment mode of this text.
     *
     * @return Returns the text alignment mode, as defined in {@link UITextLanguageAlignment}.
     * @since 1.0
     * @version 1.0
     */
    UITextLanguageAlignment GetAlign()
    {
        InitLabelButtonText();
        return labelButtonText_->GetHorAlign();
    }

    /**
     * @brief Sets the direction for this text.
     *
     * @param direct Indicates the text direction to set, as defined in {@link UITextLanguageDirect}.
     * @since 1.0
     * @version 1.0
     */
    void SetDirect(UITextLanguageDirect direct)
    {
        InitLabelButtonText();
        labelButtonText_->SetDirect(direct);
#if defined(CONFIG_SCALE_FONT_SIZE) && (CONFIG_SCALE_FONT_SIZE == 1)
        needRefresh_ = labelButtonText_->IsNeedRefresh();
#endif
    }

    /**
     * @brief Obtains the direction of this text.
     *
     * @return Returns the text direction, as defined in {@link UITextLanguageDirect}.
     * @since 1.0
     * @version 1.0
     */
    UITextLanguageDirect GetDirect()
    {
        InitLabelButtonText();
        return labelButtonText_->GetDirect();
    }

    /**
     * @brief Sets the style for this label.
     *
     * @param labelStyle Indicates the label style to set.
     * @since 1.0
     * @version 1.0
     */
    void SetLabelStyle(Style& labelStyle)
    {
        labelStyle_ = labelStyle;
#if defined(CONFIG_SCALE_FONT_SIZE) && (CONFIG_SCALE_FONT_SIZE == 1)
        needRefresh_ = true;
#endif
    }

    /**
     * @brief Sets a style for this label.
     *
     * @param key Indicates the key of the style to set.
     * @param value Indicates the value matching the key.
     * @since 1.0
     * @version 1.0
     */
    void SetLabelStyle(uint8_t key, int64_t value)
    {
        labelStyle_.SetStyle(key, value);
#if defined(CONFIG_SCALE_FONT_SIZE) && (CONFIG_SCALE_FONT_SIZE == 1)
        needRefresh_ = true;
#endif
    }

    /**
     * @brief Obtains the style of this label.
     *
     * @return Returns the label style.
     * @since 1.0
     * @version 1.0
     */
    const Style& GetLabelStyle() const
    {
        return labelStyle_;
    }

    /**
     * @brief Obtains the value of a style of this label.
     *
     * @param key Indicates the key of the style.
     * @return Returns the value of the style.
     * @since 1.0
     * @version 1.0
     */
    int64_t GetLabelStyle(uint8_t key) const
    {
        return labelStyle_.GetStyle(key);
    }

    /**
     * @brief Sets the color for this text.
     *
     * @param color Indicates the text color to set.
     * @since 1.0
     * @version 1.0
     */
    void SetTextColor(ColorType color)
    {
        labelStyle_.textColor_ = color;
    }

    /**
     * @brief Sets the font for this text.
     *
     * @param name Indicates the pointer to the font name.
     * @param size Indicates the font size to set.
     * @since 1.0
     * @version 1.0
     */
    void SetFont(const char* name, uint8_t size)
    {
        InitLabelButtonText();
#if defined(CONFIG_SCALE_FONT_SIZE) && (CONFIG_SCALE_FONT_SIZE == 1)
        labelButtonText_->SetFont(name, size, scaleRatio_);
        needRefresh_ = labelButtonText_->IsNeedRefresh();
#else
        labelButtonText_->SetFont(name, size);
#endif
    }

    /**
     * @brief Sets the font ID.
     *
     * @param fontId Indicates the font ID composed of the font name and size.
     * @since 1.0
     * @version 1.0
     */
    void SetFontId(uint16_t fontId)
    {
        InitLabelButtonText();
#if defined(CONFIG_SCALE_FONT_SIZE) && (CONFIG_SCALE_FONT_SIZE == 1)
        labelButtonText_->SetFontId(fontId, scaleRatio_);
        needRefresh_ = labelButtonText_->IsNeedRefresh();
#else
        labelButtonText_->SetFontId(fontId);
#endif
    }

    /**
     * @brief Obtains the font ID.
     *
     * @return Returns the front ID composed of the font name and size.
     * @since 1.0
     * @version 1.0
     */
    uint16_t GetFontId()
    {
        InitLabelButtonText();
        return labelButtonText_->GetFontId();
    }

#if defined(CONFIG_SCALE_FONT_SIZE) && (CONFIG_SCALE_FONT_SIZE == 1)
    /**
     * @brief Set the font size scale ratio for this labelbutton.
     *
     * @param ratio Indicates the scale value.
     * @return Returns <b>true</b> if the scale ratio set success; returns <b>false</b> otherwise.
     * @since 1.0
     * @version 1.0
     */
    bool SetFontSizeScale(float ratio);

    /**
     * @brief Obtains the font size scale ratio for this labelbutton.
     *
     * @return Returns labelbutton's current font size scale ratio.
     * @since 1.0
     * @version 1.0
     */
    float GetFontSizeScale() const;

    /**
     * @brief Obtains whether this labelbutton is scaled.
     *
     * @return Returns Returns <b>false</b> if the scale ratio is 1.0f; returns <b>false</b> otherwise.
     * @since 1.0
     * @version 1.0
     */
    bool HasFontSizeScale() const;

    /**
     * @brief Obtains the text height for this labelbutton.
     *
     * @return Returns the text height for this labelbutton.
     * @since 1.0
     * @version 1.0
     */
    int16_t GetTextHeight();

    /**
     * @brief Sets the max show lines count for this labelbutton.
     *
     * @param count Indicates the max lines count to set.
     * @since 1.0
     * @version 1.0
     */
    bool SetMaxLines(int32_t count);

    void ReMeasure() override;

    /**
     * @brief Sets this labelbutton's text area width.
     *
     * @param width Indicates text area width
     * @since 1.0
     * @version 1.0
     */
    void SetTextRectWidth(uint16_t width);

    /**
     * @brief Sets this labelbutton force remeasure
     *
     * @param flag Indicates whether use remeasure before ondraw.
     * @since 1.0
     * @version 1.0
     */
    void SetForceRemeasure(bool flag);
#endif

protected:
    virtual void InitLabelButtonText()
    {
        if (labelButtonText_ == nullptr) {
            labelButtonText_ = new Text();
            if (labelButtonText_ == nullptr) {
                GRAPHIC_LOGE("new Text fail");
                return;
            }
            labelButtonText_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
        }
    }

    Text* labelButtonText_;
#if defined(CONFIG_SCALE_FONT_SIZE) && (CONFIG_SCALE_FONT_SIZE == 1)
    bool needRefresh_ : 1;
    bool forceRemeasure_ : 1;
    float scaleRatio_;
    uint8_t maxLines_;
    int16_t limitTextHeight_;
    uint16_t ellipsisIndex_;
    uint16_t textRectWidth_;
#endif

private:
    Style labelStyle_;
    Point offset_; /* Text draw position offset */
};
} // namespace OHOS
#endif // GRAPHIC_LITE_UI_LABEL_BUTTON_H