// $Id: gc_clickpanel.cpp,v 1.13 2018/01/03 21:33:00 mkkuhner Exp $

/*
Copyright 2002-2005 Mary K. Kuhner, Peter Beerli, and Joseph Felsenstein

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/* Authors: Mary Kuhner, Jon Yamato, and Joseph Felsenstein */


#include <cassert>

#include "gc_color.h"
#include "gc_clickpanel.h"

//------------------------------------------------------------------------------------

BEGIN_EVENT_TABLE(gcClickText,wxStaticText)
EVT_MOUSE_EVENTS(gcClickText::OnMouse)
END_EVENT_TABLE()

gcClickText::gcClickText(gcClickPanel * parent, wxString label)
:
wxStaticText(parent,-1,label),
    m_parent(parent)
{
}

gcClickText::~gcClickText()
{
}

void
gcClickText::OnMouse(wxMouseEvent & event)
{
    // according to the wxWidgets documentation, calling event.Skip()
    // here might be necessary because it might be handling more basic
    // functionality (such as bringing the window to the front).
    event.Skip();

    // send this event on to the containing object. We do
    // this because which window (gcClickText, gcClickPanel, gcClickCell)
    // responds to the mouse events we're interested in does not
    // appear to be consistent across platforms.
    event.ResumePropagation(1);
}

//------------------------------------------------------------------------------------

BEGIN_EVENT_TABLE(gcClickPanel,wxPanel)
EVT_MOUSE_EVENTS(gcClickPanel::OnMouse)
END_EVENT_TABLE()

gcClickPanel::gcClickPanel(gcClickCell * parent)
:   wxPanel(parent,-1),
    m_sizer(NULL)
{
    m_sizer = new wxBoxSizer(wxVERTICAL);
}

gcClickPanel::~gcClickPanel()
{
}

void
gcClickPanel::FinishSizing()
{
    SetSizerAndFit(m_sizer);
}

void
gcClickPanel::AddText(wxString text)
{
    gcClickText* newtext = new gcClickText(this,text);

    if (text.Find("???") != wxNOT_FOUND)
    {
        newtext->SetForegroundColour(wxTheColourDatabase->Find("RED"));
    }

    RecursiveSetColour(wxTheColourDatabase->Find("WHITE"));
    m_sizer->Add(newtext,1,wxEXPAND);
}

void
gcClickPanel::CenterText(wxString text)
{
    gcClickText* newtext = new gcClickText(this,text);

    if (text.Find("???") != wxNOT_FOUND)
    {
        newtext->SetForegroundColour(wxTheColourDatabase->Find("RED"));
    }

    RecursiveSetColour(wxTheColourDatabase->Find("WHITE"));
    m_sizer->Add(new gcClickText(this,text),1,wxALIGN_CENTER);
}

void
gcClickPanel::OnMouse(wxMouseEvent & event)
{
    // according to the wxWidgets documentation, calling event.Skip()
    // here might be necessary because it might be handling more basic
    // functionality (such as bringing the window to the front).
    event.Skip();

    // send this event on to the containing object. We do
    // this because which window (gcClickText, gcClickPanel, gcClickCell)
    // responds to the mouse events we're interested in does not
    // appear to be consistent across platforms.
    event.ResumePropagation(1);
}

void
gcClickPanel::RecursiveSetColour(wxColour c)
{

    SetBackgroundColour(c);
    wxWindowList & kids = GetChildren();

    for ( wxWindowList::Node *node = kids.GetFirst(); node; node = node->GetNext() )
    {
        wxWindow * current = node->GetData();
        current->SetBackgroundColour(c);
    }

}

//------------------------------------------------------------------------------------

BEGIN_EVENT_TABLE(gcClickCell,wxPanel)
EVT_MOUSE_EVENTS(gcClickCell::OnMouse)
END_EVENT_TABLE()

gcClickCell::gcClickCell(wxWindow * parent, wxString label)
:   wxPanel(parent,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL),
    m_sizer(NULL),
    m_clickPanel(NULL),
    m_mouseInCell(false)
{
    m_sizer = new wxStaticBoxSizer(wxVERTICAL,this,label);
    m_clickPanel = new gcClickPanel(this);
    m_sizer->Add(m_clickPanel,1,wxEXPAND);
    RecursiveSetColour("wxWhite");
}

gcClickCell::~gcClickCell()
{
}

void
gcClickCell::FinishSizing()
{
    m_clickPanel->FinishSizing();
    SetSizerAndFit(m_sizer);
}

void
gcClickCell::AddText(wxString text)
{
    assert(m_clickPanel != NULL);
    m_clickPanel->AddText(text);
}

void
gcClickCell::CenterText(wxString text)
{
    assert(m_clickPanel != NULL);
    m_clickPanel->CenterText(text);
}

void
gcClickCell::OnMouse(wxMouseEvent & event)
{
    event.Skip();
    if( !event.Moving())
    {
        // we need to process events from here, but
        // we're currently only using the events
        // from the wxStaticText objects that are
        // children of this cell. This isn't quite
        // right, but each of Linux/GTK, OS X, and
        // MSW treat the events for the gcClickCell
        // itself differently, so we're punting for
        // now with this.
        if(this == event.GetEventObject()) return;

        if ( event.Entering() )
        {
            m_mouseInCell = true;
#ifdef LAMARC_COMPILE_MACOSX
            m_clickCount = 0;// HACK.HACK.HACK - 10.7 counts things wrong apparently
#endif
            NotifyEntering();
        }
        if ( event.Leaving() )
        {
            m_mouseInCell = false;
#ifdef LAMARC_COMPILE_MACOSX
            m_clickCount = 0;// HACK.HACK.HACK - 10.7 counts things wrong apparently
#endif
            NotifyLeaving();
        }
        if ( event.LeftDClick() )
        {
            wxLogVerbose(" event.LeftDClick detected");  // JMDBG

            m_mouseInCell = true;
#ifdef LAMARC_COMPILE_MACOSX
            if (m_clickCount > 1)// HACK.HACK.HACK - 10.7 counts things wrong apparently
            {
#endif
                NotifyLeftDClick();
#ifdef LAMARC_COMPILE_MACOSX
                m_clickCount = 0;// HACK.HACK.HACK - 10.7 counts things wrong apparently
            }
#endif
        }
        if ( event.LeftDown() )
        {
            wxLogVerbose(" event.LeftDown detected");  // JMDBG
            m_mouseInCell = true;
#ifdef LAMARC_COMPILE_MACOSX
            m_clickCount++;// HACK.HACK.HACK - 10.7 counts things wrong apparently
#endif

            NotifyLeftDown();
        }
        if ( event.LeftUp() )
        {
            // doesn't change m_mouseInCell because this cell
            // will get the event if the corresponding down
            // happened in the cell
            NotifyLeftUp();
        }
    }
}

void
gcClickCell::RecursiveSetColour(wxColour c)
{
    // EWFIX.P3 -- not calling SetBackgroundColour because
    // we don't appear to get click events until we pass
    // into the enclosed gcClickPanel. Turned it off since
    // it otherwise gives a false clue, but boy is this ugly.
    // SetBackgroundColour(c);

    m_clickPanel->RecursiveSetColour(c);
    Refresh();  // for MSW ??
}

void
gcClickCell::NotifyEntering()
{
    RecursiveSetColour(gccolor::enteredObject());
}

void
gcClickCell::NotifyLeaving()
{
    RecursiveSetColour(wxTheColourDatabase->Find("WHITE"));
}

void
gcClickCell::NotifyLeftDClick()
{
    wxLogDebug("Implementation Error: override NotifyLeftDClick");
}

void
gcClickCell::NotifyLeftDown()
{
    RecursiveSetColour(gccolor::activeObject());
}

void
gcClickCell::NotifyLeftUp()
{
    // EWFIX.P3 -- there should be a better way to do this
    if(m_mouseInCell)
    {
        RecursiveSetColour(gccolor::enteredObject());

    }
    else
    {
        RecursiveSetColour("wxWhite");
    }
}

//____________________________________________________________________________________
