#include "MessagesBreakpoints.h"
#include "ui_MessagesBreakpoints.h"

MessagesBreakpoints::MessagesBreakpoints(MsgBreakpointData pbpData, QWidget* parent) :
    QDialog(parent),
    ui(new Ui::MessagesBreakpoints)
{
    ui->setupUi(this);
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
    setModal(true);
    bpData = pbpData;

    int index = 0;

    filterMessages =
    {
        "ACM_", "BFFM_", "BM_", "CB_", "CBEM_", "CCM_", "CDM_", "CTL3D_", "DDM_", "DL_",
        "DM_", "DTM_", "EM_", "HDM_", "HKM_", "IE_", "IPM_", "LB_", "LVM_", "MCIWNDM_",
        "MCM_", "MN_", "MSG_", "NIN_", "OCM_", "PBM_", "PGM_", "PSM_", "RB_", "SB_",
        "SBM_", "SM_", "STM_", "TAPI_", "TB_", "TBM_", "TCM_", "TTM_", "TV_", "TVM_",
        "UDM_", "UM_", "WIZ_", "WLX_", "WM_"
    };

    BridgeList<CONSTANTINFO> constants;
    DbgFunctions()->EnumConstants(&constants);

    for(int i = 0; i < constants.Count(); i++)
    {
        foreach(QString filter, filterMessages)
        {
            if(QString(constants[i].name).startsWith(filter))
            {
                messages.insert(constants[i].value, constants[i].name);
                ui->cboxMessages->addItem(constants[i].name);
                break;
            }
        }
    }
    for(int i = 0; i < ui->cboxMessages->count(); i++)
        if(ui->cboxMessages->itemText(i) == "WM_COMMAND")
            index = i;
    ui->cboxMessages->setCurrentIndex(index);
}

MessagesBreakpoints::~MessagesBreakpoints()
{
    delete ui;
}

void MessagesBreakpoints::on_btnOk_clicked()
{
    duint procVA;
    duint wndHandle;
    QString bpCondCmd;
    bool translMsg = ui->chkTranslateMessage->isChecked();

    if(!DbgFunctions()->ValFromString(bpData.wndHandle.toUtf8().constData(), &wndHandle) ||
            !DbgFunctions()->ValFromString(bpData.procVA.toUtf8().constData(), &procVA))
        return;

    if(!DbgMemIsValidReadPtr(procVA) || !IsWindow((HWND)wndHandle))
        return;

    if(!translMsg)
    {
        BPXTYPE wBpType = DbgGetBpxTypeAt(procVA);
        if(wBpType == bp_none)
            DbgCmdExec(QString("bp 0x%1").arg(bpData.procVA));

        bpCondCmd = QString("bpcnd 0x%1, \"arg.get(1) == 0x%2").arg(bpData.procVA).arg(messages.key(ui->cboxMessages->currentText()), 1, 16);
        bpCondCmd.append(ui->rbtnBreakCurrent->isChecked() ? QString(" && arg.get(0) == 0x%1\"").arg(bpData.wndHandle) : "\"");
    }
    else
    {
        BPXTYPE wBpType = DbgGetBpxTypeAt(DbgValFromString("TranslateMessage"));
        if(wBpType == bp_none)
            DbgCmdExec("bp TranslateMessage");

#ifdef _WIN64
        bpCondCmd = QString("bpcnd TranslateMessage, \"4:[arg.get(0)+8] == 0x%1").arg(messages.key(ui->cboxMessages->currentText()), 1, 16);
        bpCondCmd.append(ui->rbtnBreakCurrent->isChecked() ? QString(" && 4:[arg.get(0)] == 0x%1\"").arg(bpData.wndHandle) : "\"");
#else //x86
        bpCondCmd = QString("bpcnd TranslateMessage, \"[arg.get(0)+4] == 0x%1").arg(messages.key(ui->cboxMessages->currentText()), 1, 16);
        bpCondCmd.append(ui->rbtnBreakCurrent->isChecked() ? QString(" && [arg.get(0)] == 0x%1\"").arg(bpData.wndHandle) : "\"");
#endif //_WIN64
    }

    DbgCmdExec(bpCondCmd);
}
