// UpgradeDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "NetConfig_VC++.h"
#include "UpgradeDlg.h"
#include "afxdialogex.h"
#include <memory>
#include "helper.h"
#include "NetConfig_VC++Dlg.h"

#define MSG_UPGRADE_STARTED     (WM_USER + 100)
#define MSG_UPGRADE_END         (WM_USER + 101)
#define MSG_SET_TIP             (WM_USER + 102)


// CUpgradeDlg 对话框

IMPLEMENT_DYNAMIC(CUpgradeDlg, CDialog)

CUpgradeDlg::CUpgradeDlg(DEV_HANDLE hDev, CWnd* pParent /*=NULL*/)
	: CDialog(CUpgradeDlg::IDD, pParent)
    , m_hDev(hDev)
    , m_password(_T(""))
{

}

CUpgradeDlg::~CUpgradeDlg()
{
    if (m_thd.joinable()) {
        m_thd.join();
    }
}

void CUpgradeDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_MFCEDITBROWSE1, m_filepathEdit);
    DDX_Control(pDX, IDC_PROGRESS1, m_progressCtrl);
    DDX_Control(pDX, IDC_STATIC_TIP, m_tipCtrl);
    DDX_Text(pDX, IDC_EDIT_PASSWORD, m_password);
}


BEGIN_MESSAGE_MAP(CUpgradeDlg, CDialog)
    ON_BN_CLICKED(IDOK, &CUpgradeDlg::OnBnClickedOk)
    ON_MESSAGE(MSG_UPGRADE_STARTED, &CUpgradeDlg::OnUpgradeStart)
    ON_MESSAGE(MSG_UPGRADE_END, &CUpgradeDlg::OnUpgradeEnd)
    ON_MESSAGE(MSG_SET_TIP, &CUpgradeDlg::OnSetTip)
    ON_WM_CLOSE()
END_MESSAGE_MAP()


// CUpgradeDlg 消息处理程序

BOOL CUpgradeDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // TODO:  在此添加额外的初始化
    m_progressCtrl.ShowWindow(SW_HIDE);
    m_tipCtrl.SetWindowText(NULL);

    return TRUE;  // return TRUE unless you set the focus to a control
    // 异常:  OCX 属性页应返回 FALSE
}

void CUpgradeDlg::OnBnClickedOk()
{
    if (m_isUpdating) {
        return;
    }

    if (m_hDev == INVALID_DEV_HANDLE) {
        MessageBox(L"请先加载设备参数！", NULL, MB_ICONWARNING);
        return;
    }

    if (m_thd.joinable()) {
        m_thd.join();
    }

    UpdateData();
    m_thd = std::thread(&CUpgradeDlg::DoUpgrade, this);
    
}

void UpgradeCb(void* ctx, float progress)
{
    CUpgradeDlg *dlg = (CUpgradeDlg*)ctx;
    CString msg;
    msg.Format(L"升级中 %.1f%%", progress);
    dlg->ShowTip(msg);

    dlg->m_progressCtrl.SetPos((int)progress);
}

void CUpgradeDlg::DoUpgrade()
{
    SendMessage(MSG_UPGRADE_STARTED);

    ZN_ERR_CODE ret = ZN_SUCCESS;
    std::string pwd;
    CString filepath;
    std::unique_ptr<unsigned char[]> data;
    unsigned int len = 0;
    CFile file;

    m_filepathEdit.GetWindowText(filepath);
    if (filepath.Trim().IsEmpty()) {
        ShowTip(L"请先选择固件文件！");
        goto END;
    }

    if (!file.Open(filepath, CFile::modeRead)) {
        ShowTip(L"固件文件访问失败！请确认路径是否正确。");
        goto END;
    }

    len = (unsigned int)file.GetLength();
    if (len == 0) {
        ShowTip(L"固件文件长度为空！");
        goto END;
    }

    data = std::unique_ptr<unsigned char[]>(new unsigned char[len]);
    memset(data.get(), 0, len);
    if (file.Read(data.get(), len) != len) {
        ShowTip(L"文件读取失败！");
        goto END;
    }
    file.Close();

    pwd = ws2s(m_password.GetString());
    ret = ZN_Upgrade(m_hDev, data.get(), len, (void*)pwd.c_str(), UpgradeCb, this);
    if (ret != ZN_SUCCESS) {
        ShowTip(L"升级失败！" + ErrorCodeStr(ret));
    }
    else {
        ShowTip(L"升级成功。");
    }

END:
    SendMessage(MSG_UPGRADE_END);
}

void CUpgradeDlg::ShowTip(const CString &tip)
{
    SendMessage(MSG_SET_TIP, (WPARAM)&tip);
}

LRESULT CUpgradeDlg::OnUpgradeStart(WPARAM w, LPARAM l)
{
    m_isUpdating = true;
    m_progressCtrl.ShowWindow(SW_SHOW);
    GetDlgItem(IDOK)->EnableWindow(FALSE);

    return 0;
}

LRESULT CUpgradeDlg::OnUpgradeEnd(WPARAM w, LPARAM l)
{
    m_progressCtrl.ShowWindow(SW_HIDE);
    GetDlgItem(IDOK)->EnableWindow(TRUE);
    m_isUpdating = false;

    return 0;
}

LRESULT CUpgradeDlg::OnSetTip(WPARAM w, LPARAM l)
{
    CString *tip = (CString*)w;
    m_tipCtrl.SetWindowText(*tip);
    return 0;
}

void CUpgradeDlg::OnClose()
{
    if (m_isUpdating) {
        MessageBox(L"升级中，请等待完成！");
        return;
    }

    CDialog::OnClose();
}
