/*=========================================================================

  Program:   WXDialog - wxWidgets X-platform GUI Front-End for CMake
  Module:    $RCSfile: PropertyList.cpp,v $
  Language:  C++
  Date:      $Date: 2012/03/29 17:21:10 $
  Version:   $Revision: 1.1.1.1 $

  Author:    Jorgen Bodde

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

/* for compilers that support precompilation
   includes "wx/wx.h" */

#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#include "PropertyList.h"
#include "app_resources.h"

#include "../cmCacheManager.h"
#include "../cmSystemTools.h"
#include "../cmake.h"

BEGIN_EVENT_TABLE( wxPropertyList, wxGrid )
    EVT_GRID_CELL_LEFT_CLICK( wxPropertyList::OnSelectCell )
    EVT_GRID_CELL_CHANGE( wxPropertyList::OnCellChange )
    EVT_GRID_CMD_CELL_RIGHT_CLICK( wxID_ANY, wxPropertyList::OnCellPopup )
    EVT_MENU ( ID_CACHE_DELETE, wxPropertyList::OnDeleteCache )
    EVT_MENU ( ID_CACHE_IGNORE, wxPropertyList::OnIgnoreCache )
    EVT_MENU ( ID_CACHE_BROWSE, wxPropertyList::OnBrowseItem )
    EVT_SIZE ( wxPropertyList::OnSizeGrid )
    EVT_CHAR ( wxPropertyList::OnKeyPressed )
END_EVENT_TABLE()

#if 0

// ----------------------------------------------------------------------------
// wxGridCellPathEditor
// ----------------------------------------------------------------------------

wxGridCellPathEditor::wxGridCellPathEditor()
{
    m_maxChars = 0;
}

void wxGridCellPathEditor::Create(wxWindow* parent,
                                  wxWindowID id,
                                  wxEvtHandler* evtHandler)
{   
    m_control = new wxTextCtrl(parent, id, wxEmptyString,
                               wxDefaultPosition, wxDefaultSize
#if defined(__WXMSW__)
                               , wxTE_PROCESS_TAB | wxTE_AUTO_SCROLL
#endif
                              );
//
//  m_button = new wxButton(parent, id+1, _("..."), 
//                          wxDefaultPosition, wxDefaultSize);
//

    // set max length allowed in the textctrl, if the parameter was set
    if (m_maxChars != 0)
    {
        ((wxTextCtrl*)m_control)->SetMaxLength(m_maxChars);
    }

    wxGridCellEditor::Create(parent, id, evtHandler);
}

void wxGridCellPathEditor::PaintBackground(const wxRect& WXUNUSED(rectCell),
                                           wxGridCellAttr * WXUNUSED(attr))
{
    // as we fill the entire client area, don't do anything here to minimize
    // flicker
}

void wxGridCellPathEditor::SetSize(const wxRect& rectOrig)
{
    wxRect rect(rectOrig);

    // Make the edit control large enough to allow for internal
    // margins
    //
    // TODO: remove this if the text ctrl sizing is improved esp. for
    // unix
    //
#if defined(__WXGTK__)
    if (rect.x != 0)
    {
        rect.x += 1;
        rect.y += 1;
        rect.width -= 1;
        rect.height -= 1;
    }
#else // !GTK
    int extra_x = ( rect.x > 2 )? 2 : 1;

// MB: treat MSW separately here otherwise the caret doesn't show
// when the editor is in the first row.
#if defined(__WXMSW__)
    int extra_y = 2;
#else
    int extra_y = ( rect.y > 2 )? 2 : 1;
#endif // MSW

#if defined(__WXMOTIF__)
    extra_x *= 2;
    extra_y *= 2;
#endif
    rect.SetLeft( wxMax(0, rect.x - extra_x) );
    rect.SetTop( wxMax(0, rect.y - extra_y) );
    rect.SetRight( rect.GetRight() + 2*extra_x );
    rect.SetBottom( rect.GetBottom() + 2*extra_y );
#endif // GTK/!GTK

    wxGridCellEditor::SetSize(rect);
}

void wxGridCellPathEditor::BeginEdit(int row, int col, wxGrid* grid)
{
    wxASSERT_MSG(m_control,
                 wxT("The wxGridCellEditor must be Created first!"));

    m_startValue = grid->GetTable()->GetValue(row, col);

    DoBeginEdit(m_startValue);
}

void wxGridCellPathEditor::DoBeginEdit(const wxString& startValue)
{
    Text()->SetValue(startValue);
    Text()->SetInsertionPointEnd();
    Text()->SetSelection(-1,-1);
    Text()->SetFocus();
}

bool wxGridCellPathEditor::EndEdit(int row, int col,
                                   wxGrid* grid)
{
    wxASSERT_MSG(m_control,
                 wxT("The wxGridCellEditor must be Created first!"));

    bool changed = false;
    wxString value = Text()->GetValue();
    if (value != m_startValue)
        changed = true;

    if (changed)
        grid->GetTable()->SetValue(row, col, value);

    m_startValue = wxEmptyString;
    // No point in setting the text of the hidden control
    //Text()->SetValue(m_startValue);

    return changed;
}


void wxGridCellPathEditor::Reset()
{
    wxASSERT_MSG(m_control,
                 wxT("The wxGridCellEditor must be Created first!"));

    DoReset(m_startValue);
}

void wxGridCellPathEditor::DoReset(const wxString& startValue)
{
    Text()->SetValue(startValue);
    Text()->SetInsertionPointEnd();
}

bool wxGridCellPathEditor::IsAcceptedKey(wxKeyEvent& event)
{
    return wxGridCellEditor::IsAcceptedKey(event);
}

void wxGridCellPathEditor::StartingKey(wxKeyEvent& event)
{
    // Since this is now happening in the EVT_CHAR event EmulateKeyPress is no
    // longer an appropriate way to get the character into the text control.
    // Do it ourselves instead.  We know that if we get this far that we have
    // a valid character, so not a whole lot of testing needs to be done.

    wxTextCtrl* tc = Text();
    wxChar ch;
    long pos;
    
#if wxUSE_UNICODE
    ch = event.GetUnicodeKey();
    if (ch <= 127)
        ch = (wxChar)event.GetKeyCode();
#else
    ch = (wxChar)event.GetKeyCode();
#endif
    switch (ch)
    {
        case WXK_DELETE:
            // delete the character at the cursor
            pos = tc->GetInsertionPoint();
            if (pos < tc->GetLastPosition())
                tc->Remove(pos, pos+1);
            break;

        case WXK_BACK:
            // delete the character before the cursor
            pos = tc->GetInsertionPoint();
            if (pos > 0)
                tc->Remove(pos-1, pos);
            break;

        default:
            tc->WriteText(ch);
            break;
    }
}

void wxGridCellPathEditor::HandleReturn( wxKeyEvent &event )
{
#if defined(__WXMOTIF__) || defined(__WXGTK__)
    // wxMotif needs a little extra help...
    size_t pos = (size_t)( Text()->GetInsertionPoint() );
    wxString s( Text()->GetValue() );
    s = s.Left(pos) + wxT("\n") + s.Mid(pos);
    Text()->SetValue(s);
    Text()->SetInsertionPoint( pos );
#else
    // the other ports can handle a Return key press
    //
    event.Skip();
#endif
}

void wxGridCellPathEditor::SetParameters(const wxString& params)
{
    if ( !params )
    {
        // reset to default
        m_maxChars = 0;
    }
    else
    {
        long tmp;
        if ( !params.ToLong(&tmp) )
        {
            wxLogDebug(_T("Invalid wxGridCellPathEditor parameter string '%s' ignored"), params.c_str());
        }
        else
        {
            m_maxChars = (size_t)tmp;
        }
    }
}

// return the value in the text control
wxString wxGridCellPathEditor::GetValue() const
{
  return Text()->GetValue();
}

#endif

/////////////////////////////////////////////////////////////////////////////
// wxPropertyItem

// returns true when this property item is a filepath
bool wxPropertyItem::IsFilePath()
{
    return m_nItemType == wxPropertyList::FILE;
}

// returns true when this property item is a dir path
bool wxPropertyItem::IsDirPath()
{
    return m_nItemType == wxPropertyList::PATH;
}

/////////////////////////////////////////////////////////////////////////////
// wxPropertyList

wxPropertyList::~wxPropertyList()
{
    WX_CLEAR_ARRAY(m_PropertyItems);
}

int wxPropertyList::AddItem(const wxString &txt)
{
    // TODO: Add the item to the grid!
    
    //int nIndex = AddString(txt);
    //return nIndex;

    return 0;
}

// order = 0 sorted (not supported yet)
// order = 1 add to top
// order = 2 add to bottom
int wxPropertyList::AddPropItem(wxPropertyItem* pItem, int order)
{
    m_PropertyItems.Add(pItem);
    if(pItem->GetAdvanced() && ! m_ShowAdvanced)
        return 0;

    // disable in progress editing
    HideControls();
        
    return AddPropertyToGrid(pItem, order);
}

int wxPropertyList::AddPropertyToGrid(wxPropertyItem *pItem, int order)
{
    int row = 0;
    if(order == 1)
        InsertRows(0,1);
    else 
    {
        AppendRows(1);    
        row = GetNumberRows() - 1;
    }
    
    // initialise the type of renderer
    if(pItem->GetItemType() == wxPropertyList::CHECKBOX)
    {
        SetCellRenderer(row, 1, new wxGridCellBoolRenderer);
        SetCellEditor(row, 1, new wxGridCellBoolEditor);
    }

#ifdef __LINUX__
    // fix to make sure scrollbars are drawn properly
    wxGrid::AdjustScrollbars();
#endif
    
    // the property display is read only
    UpdatePropertyItem(pItem, row);
    return row;
}

void wxPropertyList::AddProperty(const char* name, const char* value, const char* helpString,
                                int type, const char* comboItems, bool reverseOrder, bool advanced)
{ 
    wxPropertyItem* pItem = 0; 
   
    // add or update the property item
    for(size_t i = 0; i < m_PropertyItems.Count(); i++)
    {
        if(m_PropertyItems[i]->GetPropName().IsSameAs(name))
        {
            pItem = m_PropertyItems[i];
            if(!pItem->GetCurValue().IsSameAs(value))
            {
                pItem->SetCurValue(value);
                pItem->SetHelpString(helpString);
                pItem->SetAdvanced(advanced);
            
                // update the property item
                int row = FindProperty(pItem);
                if(row != -1)
                    UpdatePropertyItem(pItem, row);         
            }
            return;
        }
    }

    // if it is not found, then create a new one
    if(!pItem)
    {
        pItem = new wxPropertyItem(name, value, helpString, type, comboItems);
        pItem->SetAdvanced(advanced);
  
        AddPropItem(pItem, 1);
    }
}

void wxPropertyList::UpdateGridView()
{
    // make sure all items are shown, remove items that should not be shown
    bool keepItem;
    int row;
    for(size_t i = 0; i < m_PropertyItems.Count(); i++)
    {
        // to begin with, does this item fit the query?
        keepItem = m_strQuery.IsEmpty() || (m_PropertyItems[i]->GetPropName().Find(m_strQuery) != -1);
        if(keepItem)
        {
            // when advanced items are allowed to be shown, keep when ok
            if(!m_ShowAdvanced)
                keepItem = !m_PropertyItems[i]->GetAdvanced();
        }

        // find the item, if not present but keep is true, add, if 
        // present but keep is false, remove
        row = -1;
        for(size_t j = 0; j < (size_t)GetNumberRows(); j++)
        {
            if(m_PropertyItems[i]->GetPropName().IsSameAs(GetCellValue(j, 0)))
            {
                row = j;
                break;
            }
        }

        if(row == -1 && keepItem)
            AddPropertyToGrid(m_PropertyItems[i], (m_ShowAdvanced ? 2 : 0));                
        else if(row != -1 && !keepItem)
            DeleteRows(row, 1);
    }

#ifdef __LINUX__
    // fix to make sure scrollbars are drawn properly
    wxGrid::AdjustScrollbars();
#endif
}

void wxPropertyList::HideControls()
{
    DisableCellEditControl();
}

void wxPropertyList::RemoveProperty(wxPropertyItem *pItem)
{
    HideControls();
  
    // look for property in grid, delete it when present        
    for(size_t j = 0; j < (size_t)GetNumberRows(); j++)
    {
        if(pItem->GetPropName().IsSameAs(GetCellValue(j, 0), false))
        {
            DeleteRows(j, 1);                   
            
#ifdef __LINUX__
            // fix to make sure scrollbars are drawn properly
            wxGrid::AdjustScrollbars();
#endif
             break;
        }
    }

    // delete the item from the list
    m_PropertyItems.Remove(pItem);
    delete pItem;
}

wxPropertyItem *wxPropertyList::FindPropertyByName(const wxString &name)
{
    for(size_t i = 0; i < m_PropertyItems.Count(); i++)
    {
        // we have an advanced item, go through table and if not present, show it
        if(m_PropertyItems[i]->GetPropName().IsSameAs(name, true))
            return m_PropertyItems[i];
    }

    return 0;   
}

/**
void wxPropertyList::OnIgnore()
{
  if(m_curSel == -1 || this->GetCount() <= 0)
    {
    return;
    }
  wxPropertyItem* pItem = (wxPropertyItem*) GetItemDataPtr(m_curSel);
  pItem->m_curValue = "IGNORE";
  InvalidateList();
}
*/

/**
void wxPropertyList::OnDelete()
{ 
  if(m_curSel == -1 || this->GetCount() <= 0)
    {
    return;
    }
  wxPropertyItem* pItem = (wxPropertyItem*) GetItemDataPtr(m_curSel);
  m_CMakeSetupDialog->GetCMakeInstance()->GetCacheManager()->RemoveCacheEntry(pItem->m_propName);
  m_PropertyItems.erase(pItem);
  delete pItem; 
  this->DeleteString(m_curSel);
  this->HideControls();
  this->SetTopIndex(0);
  InvalidateList();
}
*/

/**
void wxPropertyList::OnHelp()
{ 
  if(m_curSel == -1 || this->GetCount() <= 0)
    {
    return;
    }
  wxPropertyItem* pItem = (wxPropertyItem*) GetItemDataPtr(m_curSel);
  MessageBox(pItem->m_HelpString, pItem->m_propName, MB_OK|MB_ICONINFORMATION);
}
*/

void wxPropertyList::RemoveAll()
{   
    WX_CLEAR_ARRAY(m_PropertyItems);
    m_generatedProjects = false;

    if(GetNumberRows() > 0) 
        DeleteRows(0, GetNumberRows());
    
    m_strQuery.Empty();

#ifdef __LINUX__
    // fix to make sure scrollbars are drawn properly
    wxGrid::AdjustScrollbars();
#endif
}

void wxPropertyList::ShowAdvanced()
{
    // set flag in the control
    m_ShowAdvanced = true; 
    UpdateGridView();
}


void wxPropertyList::HideAdvanced()
{
    // set flag in the control
    m_ShowAdvanced = false; 
    UpdateGridView();   
}

int wxPropertyList::FindProperty(wxPropertyItem *pItem)
{
    if(GetNumberRows() > 0 && pItem != 0) 
    {
        // find the property the traditional way
        for(size_t j = 0; j < (size_t)GetNumberRows(); j++)
        {
            if(pItem->GetPropName().IsSameAs(GetCellValue(j, 0)))
                return j;
        }
    }

    return -1;
}

wxPropertyItem *wxPropertyList::GetPropertyItemFromRow(int row)
{
    if(row < GetNumberRows() && row >= 0) 
    {
        wxString str = GetCellValue(row, 0);
        // find the property the traditional way
        for(size_t i = 0; i < (size_t)m_PropertyItems.Count(); i++)
        {
            if(m_PropertyItems[i]->GetPropName().IsSameAs(str))
                return m_PropertyItems[i];
        }
    }

    return 0;   
}

bool wxPropertyList::UpdatePropertyItem(wxPropertyItem *pItem, int row)
{
    wxCHECK(row < GetNumberRows(), false);

    // reflect the property's state to match the grid row

    SetReadOnly(row, 0);
    // TODO: Make this a UpdatePropItem where ADVANCED, and new edit values are reflected
    SetCellValue(row,0, pItem->GetPropName());
    
    // boolean renderer
    if(pItem->GetItemType() == wxPropertyList::CHECKBOX)
    {
        // translate ON or TRUE (case insensitive to a checkbox)
        if(pItem->GetCurValue().IsSameAs(wxT("ON"), false) ||
           pItem->GetCurValue().IsSameAs(wxT("TRUE"), false))
            SetCellValue(row, 1, wxT("1"));
        else
            SetCellValue(row, 1, wxT("0"));
    }
    else
    {
        // for normal path values, give bold in cell when
        // the NOTFOUND is present, for emphasis
        wxString str = pItem->GetPropName() + wxT("-NOTFOUND");     
        if(pItem->GetCurValue().IsSameAs(str))
        {
            wxFont fnt = GetCellFont(row, 0);       
            fnt.SetWeight(wxFONTWEIGHT_BOLD);
            SetCellFont(row, 1, fnt);
        }
        else
            SetCellFont(row, 1, GetCellFont(row, 0));

        SetCellValue(row,1, pItem->GetCurValue());
    }

    if(pItem->GetCurValue().IsSameAs("IGNORE"))
    {
        // ignored cell is completely dimmed
        wxColour col(192,192,192);
        SetCellTextColour(row, 1, col);
    }
    else
    {
        // we colour paths blue, filenames green, all else black
        wxColour col;
        if(pItem->IsDirPath())
            col.Set(0,0,255);
        else if(pItem->IsFilePath())
            col.Set(0,128,0);
        else
            col = GetCellTextColour(row, 0);

        SetCellTextColour(row, 1, col);
    }

    if(pItem->GetNewValue())
    {
        // new cell is red
        wxColour col(255,100,100);
        SetCellBackgroundColour(row, 0, col);
    }
    else
    {
        // old cell is grey
        wxColour col(192, 192, 192);
        SetCellBackgroundColour(row, 0, col);
    }

    return true;
}

void wxPropertyList::OnSelectCell( wxGridEvent& event )
{
    this->SetFocus();
    event.Skip();
}

void wxPropertyList::OnCellChange( wxGridEvent& event )
{
    int row = event.GetRow();

    wxPropertyItem *pItem = GetPropertyItemFromRow(row);
    if(pItem && row != wxNOT_FOUND)
    {
        // write propery back, and set as new
        pItem->SetNewValue(true);
        
        // write back bool
        if(pItem->GetItemType() == CHECKBOX)
        {
            if(GetCellValue(row, 1).IsSameAs("1"))
                pItem->SetCurValue("ON");
            else
                pItem->SetCurValue("OFF");
        }
        else
            pItem->SetCurValue(GetCellValue(row, 1));
    
        UpdatePropertyItem(pItem, row);
        event.Skip();
    }
}

void wxPropertyList::OnCellPopup( wxGridEvent& event )
{
    wxPoint pt;
    int row = event.GetRow();
    
    //pt = ::wxGetMousePosition();
    //ScreenToClient(pt);

    //row = YToRow(pt.y);
    if(row != wxNOT_FOUND)
    {
        wxPropertyItem *pItem = GetPropertyItemFromRow(row);
    
        if(pItem)
        {
            // select the row first if already in selection, don't
            // this will clear the previous selection
            if(!IsInSelection(row, 0))
                SelectRow(row);

            // show popup menu
            wxMenu *menu = AppResources::CreatePopupMenu();
            
            // enable when it is browsable, and selected one only
            wxMenuItem *item = menu->FindItem(ID_CACHE_BROWSE);
            if(item)
                item->Enable(IsSelectedItemBrowsable());
            
            PopupMenu(menu);

            delete menu;
        }
    }
}

void wxPropertyList::OnIgnoreCache( wxCommandEvent& event )
{
    HideControls();
  
    // ignore all selected items
    for(size_t i = 0; i < (size_t)GetNumberRows(); i++)
    {
        if(IsInSelection(i, 0))
        {
            wxPropertyItem *pItem = GetPropertyItemFromRow(i);      
            if(pItem)
            {
                pItem->SetCurValue("IGNORE");
                UpdatePropertyItem(pItem, i);
            }
        }
    }
}

void wxPropertyList::OnDeleteCache( wxCommandEvent& event )
{
    HideControls();
  
    // convert selections to prop items
    wxArrayPtrVoid items;
    for(size_t i = 0; i < (size_t)GetNumberRows(); i++)
    {
        // if selected, query for removal
        if(IsInSelection(i, 0))
        {
            wxPropertyItem *pItem = GetPropertyItemFromRow(i);      
            if(pItem)
                items.Add((void *)pItem);
        }
    }

    // now delete all prop items in cells
    for(size_t i = 0; i < items.Count(); i++)
        RemoveProperty((wxPropertyItem *)items[i]);
}

void wxPropertyList::OnBrowseItem( wxCommandEvent& event )
{
    BrowseSelectedItem();
}

bool wxPropertyList::IsSelectedItemBrowsable(int row)
{
    // when there is only one selection, and our current item
    // is browsable, make sure it can be selected.
    wxPropertyItem *pItem = 0;
    
    size_t count = 0;
    for(size_t i = 0; i < (size_t)GetNumberRows() && (count < 2); i++)
    {
        if(IsInSelection(i, 0))
        {
            if(!pItem)
                pItem = GetPropertyItemFromRow(i);
            count ++;
        }
    }

    // if we found nothing, take row (because the event EVT_GRID_CELL_SELECTED 
    // deselects the cells first before selecting the new one again
    if(row != -1 && !pItem)
    {
        pItem = GetPropertyItemFromRow(row);
        count ++; // needed because of next loop
    }

    // only one item allowed to select
    if(pItem && count == 1)
    {
        if(pItem)
            return pItem->IsDirPath() || pItem->IsFilePath();   
    }
    
    return false;
}


void wxPropertyList::BrowseSelectedItem()
{
    HideControls();
  
    for(size_t i = 0; i < (size_t)GetNumberRows(); i++)
    {
        if(IsInSelection(i, 0))
        {
            // browse for file or directory
            wxPropertyItem *pItem = GetPropertyItemFromRow(i);      
            if(pItem)
            {
                wxString title;
                wxString str = pItem->GetPropName() + _("-NOTFOUND");       
                if(pItem->GetCurValue().IsSameAs(str, true))
                    str.Empty();
                else
                    str = pItem->GetCurValue();

                // browse the directory path
                
                if(pItem->IsDirPath())
                {
                    title = _("Select path for ") + pItem->GetPropName();
                    str = ::wxDirSelector(title, str, 0, wxDefaultPosition, this);
                }
                else if(pItem->IsFilePath())
                {
                    title = _("Select file for ") + pItem->GetPropName();
                    str = ::wxFileSelector(title, str, _(""), _(""), _(MC_DEFAULT_WILDCARD), wxFILE_MUST_EXIST, this);
                }
                else
                    str.Empty();
                
                if(!str.IsEmpty())
                {
                    pItem->SetCurValue(str.c_str());
                    UpdatePropertyItem(pItem, i);
                }
            }
            
            // only allow one item to browse
            break;
        }
    }
}

void wxPropertyList::OnSizeGrid( wxSizeEvent &event )
{
    int width, height;
    
    // make sure the grid's cells are equally adjusted
    GetClientSize(&width, &height);
    SetDefaultColSize(width / 2, true);

    wxGrid::AdjustScrollbars();
}

void wxPropertyList::OnKeyPressed( wxKeyEvent &event )
{
    event.Skip();
}
