//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// copyright            : (C) 2014 Eran Ifrah
// file name            : message_pane.cpp
//
// -------------------------------------------------------------------------
// A
//              _____           _      _     _ _
//             /  __ \         | |    | |   (_) |
//             | /  \/ ___   __| | ___| |    _| |_ ___
//             | |    / _ \ / _  |/ _ \ |   | | __/ _ )
//             | \__/\ (_) | (_| |  __/ |___| | ||  __/
//              \____/\___/ \__,_|\___\_____/_|\__\___|
//
//                                                  F i l e
//
//    This program is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

#include "message_pane.h"
#include <wx/msgdlg.h>
#include <wx/dcbuffer.h>
#include "pluginmanager.h"
#include "editor_config.h"
#include "cl_config.h"

MessagePane::MessagePane( wxWindow* parent )
    : MessagePaneBase( parent )
{
    BitmapLoader* bmpLoader = PluginManager::Get()->GetStdIcons();
    m_bitmap1->SetBitmap(bmpLoader->LoadBitmap(wxT("messages/48/info")));
    m_buttonAction->Hide();
    Hide();
}

void MessagePane::OnKeyDown( wxKeyEvent& event )
{
    if (event.GetKeyCode() == WXK_ESCAPE) {
        DoHide();

    } else
        event.Skip();
}

void MessagePane::OnButtonClose( wxCommandEvent& event )
{
    wxUnusedVar(event);
    MessageDetails msg = m_messages.CurrentMessage();
    SavePreferenceIfNeeded(msg, wxNOT_FOUND); // -1 for Hide
    DoShowNextMessage();
}

void MessagePane::DoHide()
{
    if (IsShown()) {
        // Hide all default controls
        m_buttonAction->Hide();
        m_buttonAction1->Hide();
        m_buttonAction2->Hide();
        m_DontAnnoyMeCheck->Hide();

        m_messages.Clear();
        Hide();
        GetParent()->GetSizer()->Layout();
    }
}

void MessagePane::DoShowCurrentMessage()
{
    MessageDetails msg   = m_messages.CurrentMessage();
    wxString txt         = msg.message;

    m_buttonAction->Hide();
    m_buttonAction1->Hide();
    m_buttonAction2->Hide();
    m_DontAnnoyMeCheck->Hide();

    bool hasDefaultButton (false);
    if(msg.bmp.IsOk() == false) {
        BitmapLoader* bmpLoader = PluginManager::Get()->GetStdIcons();
        m_bitmap1->SetBitmap(bmpLoader->LoadBitmap(wxT("messages/48/info")));

    } else {
        m_bitmap1->SetBitmap(msg.bmp);

    }

    // display the buttons
    if (msg.btn1.buttonLabel.IsEmpty() == false) {
        m_buttonAction->SetLabel(msg.btn1.buttonLabel);
        m_buttonAction->Show();
        if(msg.btn1.isDefault) {
            m_buttonAction->SetDefault();
            hasDefaultButton = true;
        }
    }

    if (msg.btn2.buttonLabel.IsEmpty() == false) {
        m_buttonAction1->SetLabel(msg.btn2.buttonLabel);
        m_buttonAction1->Show();
        if(msg.btn2.isDefault) {
            m_buttonAction1->SetDefault();
            hasDefaultButton = true;
        }
    }

    if (msg.btn3.buttonLabel.IsEmpty() == false) {
        m_buttonAction2->SetLabel(msg.btn3.buttonLabel);
        m_buttonAction2->Show();
        if(msg.btn3.isDefault) {
            m_buttonAction2->SetDefault();
            hasDefaultButton = true;
        }
    }

    // Show hide button if needed and make the default if there is
    // no default button
    if(msg.showHideButton) {
        m_buttonClose->Show();
        if(!hasDefaultButton) {
            m_buttonClose->SetDefault();
        }
    } else {
        m_buttonClose->Hide();
    }

    m_staticTextMessage->SetLabel(txt);
    if (IsShown() == false) {
        Show();
    }

    // Show the NoSpam checkbox if needed
    m_DontAnnoyMeCheck->Show(msg.check.GetShowCheckbox());
    //Uncheck it, otherwise it will remember a stale 'tick' that the user subsequently reverted
    m_DontAnnoyMeCheck->SetValue(0);

    m_staticTextMessage->Fit();
    GetSizer()->Fit(this);
    GetParent()->GetSizer()->Layout();
    GetParent()->Refresh();
}

void MessagePane::ShowMessage(const wxString &message, bool showHideButton, const wxBitmap &bmp, const ButtonDetails& btn1, const ButtonDetails& btn2, const ButtonDetails& btn3, const CheckboxDetails& chkbox)
{
    // Dont duplicate messages...
    if(m_messages.IsExists(message))
        return;

    MessageDetails msg;
    msg.message        = message;
    msg.btn1           = btn1;
    msg.btn2           = btn2;
    msg.btn3           = btn3;
    msg.check          = chkbox;
    msg.bmp            = bmp;
    msg.showHideButton = showHideButton;
    m_messages.PushMessage(msg);
    DoShowCurrentMessage();
}

void MessagePane::OnActionButton(wxCommandEvent& event)
{
    MessageDetails msg = m_messages.CurrentMessage();
    SavePreferenceIfNeeded(msg, 0);
    DoPostEvent(msg.btn1);
    DoShowNextMessage();
}

void MessagePane::DoShowNextMessage()
{
    m_messages.PopMessage();
    if (m_messages.IsEmpty()) {
        DoHide();
        return;
    }

    DoShowCurrentMessage();
}

/////////////////////////////////////////////////////////////////////////////
//

bool MessagePaneData::IsExists(const wxString &msg)
{
    for(size_t i=0; i<m_queue.size(); i++) {
        if(msg == m_queue.at(i).message)
            return true;
    }
    return false;
}

void MessagePaneData::Clear()
{
    m_queue.clear();
}

MessageDetails MessagePaneData::CurrentMessage()
{
    if (m_queue.empty())
        return MessageDetails();

    return m_queue.back();
}

bool MessagePaneData::IsEmpty()
{
    return m_queue.empty();
}

void MessagePaneData::PopMessage()
{
    if (m_queue.empty())
        return;

    m_queue.pop_back();
}

void MessagePaneData::PushMessage(const MessageDetails& msg)
{
    m_queue.push_back(msg);
}

void MessagePane::OnEraseBG(wxEraseEvent& event)
{
    wxUnusedVar(event);
}

void MessagePane::OnPaint(wxPaintEvent& event)
{
    wxBufferedPaintDC dc(this);
//	wxRect rr = GetClientRect();
//
//	dc.SetPen(  wxPen  (wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)));
//	dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)));
//	dc.DrawRectangle(rr);
//
//	rr.Deflate(1);
//	dc.SetPen(wxPen( *wxRED_PEN ));
//	dc.SetBrush( *wxTRANSPARENT_BRUSH );
//
//	dc.DrawRectangle(rr);
}

void MessagePane::OnActionButton1(wxCommandEvent& event)
{
    MessageDetails msg = m_messages.CurrentMessage();
    SavePreferenceIfNeeded(msg, 1);
    DoPostEvent(msg.btn2);
    DoShowNextMessage();
}

void MessagePane::OnActionButton2(wxCommandEvent& event)
{
    MessageDetails msg = m_messages.CurrentMessage();
    SavePreferenceIfNeeded(msg, 2);
    DoPostEvent(msg.btn3);
    DoShowNextMessage();
}

void MessagePane::DoPostEvent(ButtonDetails btn)
{
    if (btn.commandId != wxNOT_FOUND && btn.window) {
        if(btn.menuCommand) {
            wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, btn.commandId);
            btn.window->AddPendingEvent(evt);
        } else {
            wxCommandEvent evt(btn.commandId);
            btn.window->AddPendingEvent(evt);
        }
    }
}

void MessagePane::SavePreferenceIfNeeded(const MessageDetails msg, int choice)
{
    // If the checkbox is both shown (to cater for random ticks) and checked, save the preference
    if (choice != wxNOT_FOUND && m_DontAnnoyMeCheck->IsShown() && m_DontAnnoyMeCheck->IsChecked()) {
        wxString label = msg.check.GetLabel();
        if (!label.IsEmpty()) {
            clConfig::Get().SetAnnoyingDlgAnswer(label, choice+1); // +1 to skip the Hide button
        }
    }

    if(choice == wxNOT_FOUND && m_DontAnnoyMeCheck->IsShown()) {
        wxString label = msg.check.GetLabel();
        if (!label.IsEmpty()) {
            clConfig::Get().SetAnnoyingDlgAnswer(label, m_DontAnnoyMeCheck->IsChecked() ? 1 : 0 );
        }
    }
}
