#include "pch.h"
#include "app.h"
#include "log.h"
#include "node_text_input.h"
#include "node_border.h"

Node* NodeTextInput::clone_instantiate() const
{
    return new NodeTextInput();
}

void NodeTextInput::on_tick(float dt)
{
    timer += dt;
    if (timer > 1.0)
    {
        timer = 0;
        if (m_cursor)
        {
            m_cursor->m_display = !m_cursor->m_display;
            app_redraw();
        }
    }
}

void NodeTextInput::clone_finalize(Node* dest) const
{
    NodeBorder::clone_copy(dest);
    NodeTextInput* n = static_cast<NodeTextInput*>(dest);
    if (n->m_children.size())
    {
        n->m_text = (NodeText*)n->m_children[0].get();
        n->m_cursor = (NodeBorder*)n->m_children[1].get();
    }
    n->m_string = m_string;
    
}

void NodeTextInput::init()
{
    init_controls();
}

void NodeTextInput::init_controls()
{
    m_text = new NodeText;
    add_child(m_text);
    m_text->m_font = "arial";
    m_text->m_font_size = 11;
    m_text->m_text = "TextInput";
    m_text->create();
    m_string = "TextInput";
    YGNodeStyleSetFlexDirection(y_node, YGFlexDirectionRow);
    m_cursor = add_child<NodeBorder>();
    m_cursor->SetWidth(4);
    m_cursor->SetHeightP(100);
    m_cursor->SetMargin(0, 0, 0, 2);
}

kEventResult NodeTextInput::handle_event(Event* e)
{
    KeyEvent* ke = (KeyEvent*)e;
    switch (e->m_type)
    {
    case kEventType::MouseDownL:
        App::I.showKeyboard();
        break;
    case kEventType::MouseUpL:
        key_capture();
        break;
    case kEventType::KeyDown:
        //switch (ke->m_key)
        //{
        //case VK_BACK:
        //    m_string.erase(m_string.end() - 1);
        //    m_text->set_text(m_string.c_str());
        //    break;
        //default:
        //    break;
        //}
        break;
    case kEventType::KeyUp:
        if (ke->m_key == kKey::KeyEnter && on_return)
            on_return(this);
        if (ke->m_key == kKey::KeyBackspace)
        {
            if (!m_string.empty())
            {
                m_string.erase(m_string.end() - 1);
                m_text->set_text(m_string.c_str());
            }
        }
        break;
    case kEventType::KeyChar:
        if (m_cursor)
        {
            timer = 0;
            m_cursor->m_display = true;
        }
        if (ke->m_char == '\b' // backspace
            || ke->m_char == 0x7f // DEL
                )
        {
            if (!m_string.empty())
            {
                m_string.erase(m_string.end() - 1);
                m_text->set_text(m_string.c_str());
            }
        }
        else if (ke->m_char == '\n' || ke->m_char == '\r') // enter/return
        {
            if (on_return)
                on_return(this);
        }
        else if (ke->m_char >= 32 && ke->m_char < (32 + 96))
        {
            m_string += (char)ke->m_char;
            m_text->set_text(m_string.c_str());
        }
        break;
    default:
        return kEventResult::Available;
        break;
    }
    return kEventResult::Consumed;
}

void NodeTextInput::set_text(const std::string& s)
{
    if (m_text)
        m_text->set_text(s.c_str());
    m_string = s;
}

