#pragma once
#include <memory>

#include "XmlElement.h"
#include "XmlAttribute.h"

class HtmlElement : public XmlElement
{
public:
    enum class Type
    {
        NONE,
        BODY,
        HEAD,
        PARAGRAPH,
        TEXT_RUN,
        CODE,
        HEADING,
        HYPERLINK,
        IMAGE,
        UNORDERED_LIST,
        LIST_ITEM,
        DIV
    };

    HtmlElement(const std::string& tagName);

    virtual Type getType() const = 0;
};

class HtmlDivElement : public HtmlElement
{
public:
    HtmlDivElement() : HtmlElement("div")
    {

    }

    Type getType() const override
    {
        return Type::DIV;
    }
};

class HtmlCodeElement : public HtmlElement
{
public:
    HtmlCodeElement() : HtmlElement("code")
    {

    }

    Type getType() const override
    {
        return Type::CODE;
    }
};

class HtmlHeadingElement : public HtmlElement
{
public:
    HtmlHeadingElement(unsigned index) : HtmlElement("h" + std::to_string(index))
    {

    }

    Type getType() const override
    {
        return Type::HEADING;
    }
};

class HtmlHyperlinkElement : public HtmlElement
{
public:
    HtmlHyperlinkElement(const std::string& href) : HtmlElement("a")
    {
        if(!href.empty())
        {
            auto href_attr = std::make_unique<XmlAttribute>("href");
            href_attr->setValue(href);
            addAttribute(std::move(href_attr));
        }
    }

    Type getType() const override
    {
        return Type::HYPERLINK;
    }
};

class HtmlImageElement : public HtmlElement
{
public:
    HtmlImageElement(const std::string& src, const std::string& alt) : HtmlElement("img")
    {
        if(!src.empty())
        {
            auto href_attr = std::make_unique<XmlAttribute>("src");
            href_attr->setValue(src);
            addAttribute(std::move(href_attr));
        }

        if(!alt.empty())
        {
            auto href_attr = std::make_unique<XmlAttribute>("alt");
            href_attr->setValue(alt);
            addAttribute(std::move(href_attr));
        }
    }

    Type getType() const override
    {
        return Type::IMAGE;
    }
};

class HtmlUnorderedList : public HtmlElement
{
public:
    HtmlUnorderedList() : HtmlElement("ul")
    {
    }

    Type getType() const override
    {
        return Type::UNORDERED_LIST;
    }
};

class HtmlListItem : public HtmlElement
{
public:
    HtmlListItem() : HtmlElement("li")
    {
    }

    Type getType() const override
    {
        return Type::LIST_ITEM;
    }
};

using HtmlElementUPtr = std::unique_ptr<HtmlElement>;
