#include "RemoteControl.h"
#include "LogControl.h"
#include <ClientCore.h>
#include <InfoCommunicate.hpp>

RemoteControl::RemoteControl(wxWindow* parent, std::shared_ptr<ClientCore>& clientCore) : wxPanel(parent), clientCore_(clientCore)
{
    Init();
    SetGrid();
    BindEvent();
}

RemoteControl::~RemoteControl()
{
}

void RemoteControl::Init()
{
    grid_ = new wxGrid(this, wxID_ANY);
    auto* topSizer = new wxBoxSizer(wxVERTICAL);

    auto* dirSizer = new wxBoxSizer(wxHORIZONTAL);
    textCtrl_ = new wxTextCtrl(this, wxID_ANY);
    dirSizer->Add(textCtrl_, 1, wxALL | wxEXPAND, gBorder);

    edRemoteId_ = new wxTextCtrl(this, wxID_ANY);
    edRemoteId_->SetMinSize(wxSize(200, -1));
    edRemoteId_->SetEditable(false);
    dirSizer->Add(edRemoteId_, 0, wxALL | wxCENTER, gBorder);

    btnHome_ = new wxButton(this, wxID_ANY, _("Home"));
    dirSizer->Add(btnHome_, 0, wxALL | wxCENTER, gBorder);

    btnGet_ = new wxButton(this, wxID_ANY, _("Get"));
    dirSizer->Add(btnGet_, 0, wxALL | wxCENTER, gBorder);

    btnUpLevel_ = new wxButton(this, wxID_ANY, _("UpLevel"));
    dirSizer->Add(btnUpLevel_, 0, wxALL | wxCENTER, gBorder);

    btnRefresh_ = new wxButton(this, wxID_ANY, _("Refresh"));
    dirSizer->Add(btnRefresh_, 0, wxALL | wxCENTER, gBorder);

    auto* bottomSizer = new wxBoxSizer(wxHORIZONTAL);
    bottomSizer->Add(grid_, 1, wxEXPAND);

    topSizer->Add(dirSizer, 0, wxALL | wxEXPAND);
    topSizer->Add(bottomSizer, 1, wxEXPAND | wxCENTER);
    SetSizer(topSizer);
    Layout();
}

void RemoteControl::BindEvent()
{
    Bind(wxEVT_BUTTON, &RemoteControl::AskHome, this, btnHome_->GetId());
    clientCore_->SetHomeCallback([this](const wxString& home) {
        textCtrl_->SetValue(home);
        logControl_->AddLog(_("Remote Home: %s"), home);
    });
    Bind(wxEVT_BUTTON, &RemoteControl::GetDirContent, this, btnGet_->GetId());
    clientCore_->SetDirFileCallback([this](const DirFileInfoVec& dirInfoVec) {
        if (grid_->GetNumberRows() > 0) {
            grid_->DeleteRows(0, grid_->GetNumberRows());
        }
        for (auto& dirInfo : dirInfoVec.vec) {
            grid_->AppendRows();
            auto wxPath = wxString::FromUTF8(dirInfo.fullPath);
            grid_->SetCellValue(grid_->GetNumberRows() - 1, 0, wxPath);
            grid_->SetCellValue(grid_->GetNumberRows() - 1, 1, DirFileInfo::GetFileSize(dirInfo.size));
            grid_->SetCellValue(grid_->GetNumberRows() - 1, 2, DirFileInfo::GetFileTypeName(dirInfo.type));
            grid_->SetCellValue(grid_->GetNumberRows() - 1, 3, DirFileInfo::GetStrTime(dirInfo.lastModifyTime));
            grid_->SetCellValue(grid_->GetNumberRows() - 1, 4, wxString::Format("%o", dirInfo.permission));
        }
    });
}

void RemoteControl::AskHome(wxCommandEvent& event)
{
    auto remoteId = edRemoteId_->GetValue();
    if (remoteId.empty()) {
        logControl_->AddLog(_("Remote ID is Empty."));
        return;
    }
    InfoCommunicate infoCommunicate;
    if (!clientCore_->Send<InfoCommunicate>(infoCommunicate, FBT_CLI_ASK_HOME, remoteId)) {
        logControl_->AddLog(_("Request ask %s's Home Failed"), remoteId);
    } else {
        logControl_->AddLog(_("Request ask %s's Home Success"), remoteId);
    }
}

void RemoteControl::GetDirContent(wxCommandEvent& event)
{
    auto remoteId = edRemoteId_->GetValue();
    if (remoteId.empty()) {
        logControl_->AddLog(_("Remote ID is Empty."));
        return;
    }
    auto home = textCtrl_->GetValue();
    if (home.empty()) {
        logControl_->AddLog(_("Remote Home is Empty."));
        return;
    }
    InfoCommunicate info;
    info.data = home.ToStdString();
    if (!clientCore_->Send<InfoCommunicate>(info, FBT_CLI_ASK_DIRFILE, remoteId)) {
        logControl_->AddLog(_("Request get %s's DirFile Failed"), home);
    } else {
        logControl_->AddLog(_("Request get %s's DirFile Success"), home);
    }
}

void RemoteControl::SetGrid()
{
    grid_->CreateGrid(10, 5);
    grid_->SetColLabelValue(0, _("FullPath"));
    grid_->SetColLabelValue(1, _("FileSize"));
    grid_->SetColLabelValue(2, _("FileType"));
    grid_->SetColLabelValue(3, _("LastModified"));
    grid_->SetColLabelValue(4, _("Permissions"));

    grid_->SetColSize(0, 200);
    grid_->SetColSize(1, 100);
    grid_->SetColSize(2, 100);
    grid_->SetColSize(3, 150);
    grid_->SetColSize(4, 100);
}

void RemoteControl::setRemoteID(const wxString& id)
{
    logControl_->AddLog(_("You Selected Remote ID: ") + id);
    edRemoteId_->SetValue(id);
}

void RemoteControl::SetLogControl(LogControl* logControl)
{
    logControl_ = logControl;
}