/*********************************************************************
 * Name:      	main.cpp
 * Purpose:   	Implements simple wxWidgets application with GUI
 * 				created using wxFormBuilder.
 * Author:
 * Created:
 * Copyright:
 * License:   	wxWidgets license (www.wxwidgets.org)
 *
 * Notes:		Note that all GUI creation code is implemented in
 * 				gui.cpp source file which is generated by wxFormBuilder.
 *********************************************************************/
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "findit.h"
#include "findit_pi.h"
#include "tinyxml/tinyxml.h"

#include <wx/tokenzr.h>
#include "wx/stdpaths.h"
#include <wx/dir.h>
#include <wx/arrimpl.cpp>

#include "jsonval.h"
#include "jsonwriter.h"


MainDialog::MainDialog(wxWindow* parent,findit_pi *p) : FindItDialog( parent )
{
    pPlugin = p;
}

MainDialog::~MainDialog()
{

}

void MainDialog::OnCloseDialog(wxCloseEvent& event)
{
    saveData();
    pPlugin->DeInit();
}

void MainDialog::OnOKClick(wxCommandEvent& event)
{
    saveData();
    pPlugin->DeInit();
}

void MainDialog::OnCancelClick(wxCommandEvent& event)
{
    pPlugin->DeInit();
}

void MainDialog::OnInit( wxInitDialogEvent& event )
{
    searchStringCountMaterial = searchStringCountFood = 0;
    lastRowSelectedMaterial   = lastRowSelectedFood   = 0;
    lastColSelectedMaterial   = lastColSelectedFood   = 0;

    myGridStringTable* material = new myGridStringTable(1,this->m_gridMaterial->GetNumberCols());
    for(int i = 0; i < this->m_gridMaterial->GetNumberCols(); i++)
        material->SetColLabelValue(i,this->m_gridMaterial->GetColLabelValue(i));
    this->m_gridMaterial->SetTable(material,true);
#ifdef __WXOSX__
    this->m_gridMaterial->SetTabBehaviour(wxGrid::Tab_Wrap);
#endif
    this->m_gridMaterial->DeleteRows();

    myGridStringTable* food = new myGridStringTable(1,this->m_gridFood->GetNumberCols());
    for(int i = 0; i < this->m_gridFood->GetNumberCols(); i++)
        food->SetColLabelValue(i,this->m_gridFood->GetColLabelValue(i));
    this->m_gridFood->SetTable(food,true);
#ifdef __WXOSX__
    this->m_gridFood->SetTabBehaviour(wxGrid::Tab_Wrap);
#endif
    this->m_gridFood->DeleteRows();

#ifndef __WXOSX__
    unit.Add(_T(""));

    location1.Add(wxEmptyString);
    location2.Add(wxEmptyString);
    location3.Add(wxEmptyString);
    location4.Add(wxEmptyString);
    location5.Add(wxEmptyString);
    location6.Add(wxEmptyString);
#endif

    prioritystr.Add(_T("0"));
    prioritystr.Add(_T("1"));
    prioritystr.Add(_T("2"));
    prioritystr.Add(_T("3"));
    prioritystr.Add(_T("4"));
    prioritystr.Add(_T("5"));

    wxStandardPathsBase& std_path = wxStandardPathsBase::Get();
#ifdef __WXMSW__
    wxString stdPath  = std_path.GetConfigDir();
#endif
#ifdef __WXGTK__
    wxString stdPath  = std_path.GetUserDataDir();
#endif
#ifdef __WXOSX__
    wxString stdPath  = std_path.GetUserConfigDir();   // should be ~/Library/Preferences
#endif


    wxString pathSeparator = wxFileName::GetPathSeparator();
    pHome_Locn = stdPath + pathSeparator;
    pHome_Locn += _T("plugins") + pathSeparator;
    pHome_Locn += _T("FindIt") + pathSeparator;

    if(!wxDir::Exists(pHome_Locn))
        wxMkdir(pHome_Locn);

    this->m_gridLocations->ClearGrid();

    loadData();

    this->m_notebook1->SetSelection(0);
#ifndef __WXOSX__
    this->m_textCtrl1->SetFocus(); // Such-Funktion aktivieren
#endif
    setLogbookColumns(pPlugin->isLogbookReady);
}

void MainDialog::setLogbookColumns(bool logbookReady)
{
    m_buttonBuyItMaterial->Show(logbookReady);
    m_buttonBuyItFood->Show(logbookReady);

    if(!logbookReady)
    {
        m_gridMaterial->SetColMinimalAcceptableWidth(0);
        m_gridFood->SetColMinimalAcceptableWidth(0);

        for(int col = BUY; col < UNIT; col++)
        {
            if(col == ACTUELL) continue;
            m_gridMaterial->SetColSize(col,0);
            m_gridFood->SetColSize(col,0);
        }
    }
    else if(m_gridMaterial->GetColSize(BUY) == 0)
    {
        for(int col = BUY; col < UNIT; col++)
        {
//			if(col == ACTUELL) continue;
            m_gridMaterial->SetColSize(col,50);
            m_gridFood->SetColSize(col,50);
        }
    }

    this->Refresh();
}

void MainDialog::OnGridLabelLClickFood( wxGridEvent& event )
{
    int row, col;
    row = event.GetRow();
    col = event.GetCol();

    this->m_gridFood->SetFocus();

    if(row != -1 || (row == -1 && col == -1))
    {
        event.Skip();
        return;
    }
    this->m_gridFood->SetGridCursor(0,col);

    static bool ascending = true;
    sortGrid(this->m_gridFood,col,ascending);
    ascending = !ascending;
}

void MainDialog::OnGridLabelLClickMaterial( wxGridEvent& event )
{
    int row, col;
    row = event.GetRow();
    col = event.GetCol();

    this->m_gridMaterial->SetFocus();

    if(row != -1 || (row == -1 && col == -1))
    {
        event.Skip();
        return;
    }
    this->m_gridMaterial->SetGridCursor(0,col);

    static bool ascending = true;
    sortGrid(this->m_gridMaterial, col,ascending);
    ascending = !ascending;
}

void MainDialog::sortGrid(wxGrid* grid, int col, bool ascending)
{
    bool sort = false;
    myGridStringTable* data = (myGridStringTable*)grid->GetTable();

    wxGridStringArray arr = data->m_data;
    if(arr.Count() < 2) return;

    wxGridStringArray temp;

    temp .Add(arr[0]);
    int i;
    do
    {
        sort = false;
        i = 0;
        do
        {
            if(ascending)
            {
                if((arr[i][col] > arr[i+1][col]))
                {
                    temp[0] = arr[i];
                    arr[i]  = arr[i+1];
                    arr[i+1]  = temp[0];
                    sort = true;
                }
            }
            else
            {
                if((arr[i+1][col] > arr[i][col]))
                {
                    temp[0] = arr[i];
                    arr[i]  = arr[i+1];
                    arr[i+1]  = temp[0];
                    sort = true;
                }
            }
            i++;
        }
        while(i < grid->GetNumberRows()-1);
    }
    while(sort);
    data->m_data = arr;

    grid->ForceRefresh();
}

void MainDialog::OnGridCellChangeMaterial( wxGridEvent& event )
{
    int col = event.GetCol();
    int row = event.GetRow();

    if( col == QUOTA || col == ACTUELL)
    {
        if(this->m_gridMaterial->GetCellValue(row,ACTUELL) != wxEmptyString)
        {
            int quota = atoi(this->m_gridMaterial->GetCellValue(row,QUOTA).mb_str());
            int act   = atoi(this->m_gridMaterial->GetCellValue(row,ACTUELL).mb_str());

            if(act < quota)
            {
                this->m_gridMaterial->SetCellValue(row,BUY,_("Yes"));
                this->m_gridMaterial->SetCellValue(row,TOBUY,wxString::Format(_T("%i"),quota-act));
            }
            else
            {
                if(!pPlugin->buyNo)
                    this->m_gridMaterial->SetCellValue(row,BUY,_T(""));
                else
                    this->m_gridMaterial->SetCellValue(row,BUY,_("No"));

                if(!pPlugin->toBuyZero)
                    this->m_gridMaterial->SetCellValue(row,TOBUY,_T(""));
                else
                    this->m_gridMaterial->SetCellValue(row,TOBUY,_T("0"));
            }
        }
    }

    if(col == TOBUY)
    {
        if(wxAtoi(this->m_gridMaterial->GetCellValue(row,TOBUY)) > 0)
            m_gridMaterial->SetCellValue(row,BUY,_("Yes"));

        if(wxAtoi(this->m_gridMaterial->GetCellValue(row,TOBUY)) == 0 && pPlugin->buyNo == 1)
            m_gridMaterial->SetCellValue(row,BUY,_("No"));
        if(wxAtoi(this->m_gridMaterial->GetCellValue(row,TOBUY)) == 0 && pPlugin->buyNo == 0)
            m_gridMaterial->SetCellValue(row,BUY,_T(""));
    }
}

void MainDialog::reloadData()
{
    saveData();

    if(this->m_gridMaterial->GetNumberRows())
        this->m_gridMaterial->DeleteRows (0,this->m_gridMaterial->GetNumberRows());
    if(this->m_gridFood->GetNumberRows())
        this->m_gridFood->DeleteRows     (0,this->m_gridFood->GetNumberRows());
    if(this->m_gridUnits->GetNumberRows())
        this->m_gridUnits->DeleteRows    (0,this->m_gridUnits->GetNumberRows());
    if(this->m_gridLocations->GetNumberRows())
        this->m_gridLocations->DeleteRows(0,this->m_gridLocations->GetNumberRows());
    location1.clear();
    location2.clear();
    location3.clear();
    location4.clear();
    location5.clear();
    location6.clear();
    unit.clear();

    loadData();
    this->Refresh();
}

void MainDialog::OnGridCellChangeFood( wxGridEvent& event )
{
    int col = event.GetCol();
    int row = event.GetRow();

    if( col == QUOTA || col == ACTUELL)
    {
        if(this->m_gridFood->GetCellValue(row,ACTUELL) != wxEmptyString)
        {
            int quota = atoi(this->m_gridFood->GetCellValue(row,QUOTA).mb_str());
            int act   = atoi(this->m_gridFood->GetCellValue(row,ACTUELL).mb_str());

            if(act < quota)
            {
                this->m_gridFood->SetCellValue(row,BUY,_("Yes"));
                this->m_gridFood->SetCellValue(row,TOBUY,wxString::Format(_T("%i"),quota-act));
            }
            else
            {
                if(!pPlugin->buyNo)
                    this->m_gridFood->SetCellValue(row,BUY,_T(""));
                else
                    this->m_gridFood->SetCellValue(row,BUY,_("No"));

                if(!pPlugin->toBuyZero)
                    this->m_gridFood->SetCellValue(row,TOBUY,_T(""));
                else
                    this->m_gridFood->SetCellValue(row,TOBUY,_T("0"));
            }
        }
    }

    if(col == TOBUY)
    {
        if(wxAtoi(this->m_gridFood->GetCellValue(row,TOBUY)) > 0)
            m_gridFood->SetCellValue(row,BUY,_("Yes"));

        if(wxAtoi(this->m_gridFood->GetCellValue(row,TOBUY)) == 0 && pPlugin->buyNo == 1)
            m_gridFood->SetCellValue(row,BUY,_("No"));
        if(wxAtoi(this->m_gridFood->GetCellValue(row,TOBUY)) == 0 && pPlugin->buyNo == 0)
            m_gridFood->SetCellValue(row,BUY,_T(""));
    }
}

void MainDialog::OnButtonClickBuyFood( wxCommandEvent& event )
{
    wxJSONValue v;
    long val, tobuy;
    bool write = false;
    int ind = 0;

    for(int i = 0; i < this->m_gridFood->GetNumberRows(); i++)
    {
        if(this->m_gridFood->GetCellValue(i,BUY) != wxEmptyString && this->m_gridFood->GetCellValue(i,BUY) != _("No"))
        {
            this->m_gridFood->GetCellValue(i,PRIORITY).ToLong(&val);
            v[ind][_T("Priority")] = (int) val;
            v[ind][_T("Category")] = _("Provisions");
            v[ind][_T("PluginName")] = _T("FindIt");
            this->m_gridFood->GetCellValue(i,TOBUY).ToLong(&tobuy);
            v[ind][_T("Amount")] = tobuy;
            v[ind][_T("Unit")] = this->m_gridFood->GetCellValue(i,UNIT);
            v[ind++][_T("Text")] = this->m_gridFood->GetCellValue(i,TEXT);
            write = true;

            //	this->m_gridFood->SetCellValue(i,BUY,_T(""));
        }
    }

    if(write)
    {
        wxJSONWriter w;
        wxString out;
        w.Write(v, out);

        SendPluginMessage(wxString(_T("LOGBOOK_BUYPARTS_ADDLINE_REQUEST")),out);
    }
}

void MainDialog::OnButtonClickBuyMaterial( wxCommandEvent& event )
{
    wxJSONValue v = NULL;
    long val, tobuy;
    bool write = false;
    int ind = 0;

    for(int i = 0; i < this->m_gridMaterial->GetNumberRows(); i++)
    {
        if(this->m_gridMaterial->GetCellValue(i,BUY) != wxEmptyString && this->m_gridMaterial->GetCellValue(i,BUY) != _("No"))
        {
            this->m_gridMaterial->GetCellValue(i,PRIORITY).ToLong(&val);
            v[ind][_T("Priority")] = (int) val;
            v[ind][_T("Category")] = _("Material");
            v[ind][_T("PluginName")] = _T("FindIt");
            this->m_gridMaterial->GetCellValue(i,TOBUY).ToLong(&tobuy);
            v[ind][_T("Amount")] = tobuy;
            v[ind][_T("Unit")] = this->m_gridMaterial->GetCellValue(i,UNIT);
            v[ind++][_T("Text")] = this->m_gridMaterial->GetCellValue(i,TEXT);
            write = true;

//			if(pPlugin->buyNo)
//				this->m_gridMaterial->SetCellValue(i,BUY,_T(""));
        }
    }

    if(write)
    {
        wxJSONWriter w;
        wxString out;
        w.Write(v, out);
        SendPluginMessage(wxString(_T("LOGBOOK_BUYPARTS_ADDLINE_REQUEST")),out);
    }
}

void MainDialog::OnButtonClickMaterialAdd( wxCommandEvent& event )
{
    lastRowSelectedMaterial = addLineMaterial();
    lastColSelectedMaterial = PRIORITY;

    if(pPlugin->lastRowDefault == 1)
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,BUY,_("No"));

    if(lastRowSelectedMaterial != 0 && pPlugin->lastRowDefault == 0)
    {
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,BUY,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,BUY));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,PRIORITY,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,PRIORITY));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,QUOTA,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,QUOTA));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,ACTUELL,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,ACTUELL));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,TOBUY,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,TOBUY));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,UNIT,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,UNIT));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,LOC1,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,LOC1));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,LOC2,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,LOC2));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,LOC3,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,LOC3));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,LOC4,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,LOC4));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,LOC5,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,LOC5));
        this->m_gridMaterial->SetCellValue(lastRowSelectedMaterial,LOC6,this->m_gridMaterial->GetCellValue(lastRowSelectedMaterial-1,LOC6));
    }

    this->m_gridMaterial->SetFocus();
    this->m_gridMaterial->MakeCellVisible(lastRowSelectedMaterial,PRIORITY);
    this->m_gridMaterial->SetGridCursor(lastRowSelectedMaterial,PRIORITY);
}

void MainDialog::OnButtonClickAddLineFood( wxCommandEvent& event )
{
    lastRowSelectedFood = addLineFood();
    lastColSelectedFood = PRIORITY;

    if(pPlugin->lastRowDefault == 1)
        this->m_gridFood->SetCellValue(lastRowSelectedFood,BUY,_("No"));

    if(lastRowSelectedFood != 0 && pPlugin->lastRowDefault == 0)
    {
        this->m_gridFood->SetCellValue(lastRowSelectedFood,BUY,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,BUY));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,PRIORITY,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,PRIORITY));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,QUOTA,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,QUOTA));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,ACTUELL,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,ACTUELL));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,TOBUY,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,TOBUY));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,UNIT,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,UNIT));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,LOC1,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,LOC1));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,LOC2,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,LOC2));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,LOC3,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,LOC3));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,LOC4,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,LOC4));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,LOC5,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,LOC5));
        this->m_gridFood->SetCellValue(lastRowSelectedFood,LOC6,this->m_gridFood->GetCellValue(lastRowSelectedFood-1,LOC6));
    }

    this->m_gridFood->SetFocus();
    this->m_gridFood->MakeCellVisible(lastRowSelectedFood,PRIORITY);
    this->m_gridFood->SetGridCursor(lastRowSelectedFood,PRIORITY);
}

void MainDialog::OnGridCellLeftClickMaterial( wxGridEvent& event )
{
    this->lastRowSelectedMaterial = event.GetRow();
    this->lastColSelectedMaterial = event.GetCol();
    event.Skip();
}

void MainDialog::OnGridCellLeftClickFood( wxGridEvent& event )
{
    this->lastRowSelectedFood = event.GetRow();
    this->lastColSelectedFood = event.GetCol();
    event.Skip();
}


void MainDialog::onButtonClickAddLineLocations( wxCommandEvent& event )
{
    this->m_gridLocations->AppendRows();
    lastRowSelectedLocations = m_gridLocations->GetNumberRows()-1;
    lastColSelectedLocations = 0;
    this->m_gridLocations->SetFocus();
    this->m_gridLocations->MakeCellVisible(lastRowSelectedLocations,0);
    this->m_gridLocations->SetGridCursor(lastRowSelectedLocations,0);
}

void MainDialog::OnButtonClickUnitsAddLine( wxCommandEvent& event )
{
    this->m_gridUnits->AppendRows();
    lastRowSelectedUnits = m_gridUnits->GetNumberRows()-1;
    lastColSelectedUnits = 0;
    this->m_gridUnits->SetFocus();
    this->m_gridUnits->MakeCellVisible(lastRowSelectedUnits,0);
    this->m_gridUnits->SetGridCursor(lastRowSelectedUnits,0);
}

void MainDialog::OnCharMaterial( wxKeyEvent& event )
{
    if(!deleteGridRow(event.GetKeyCode(),m_gridMaterial))
        event.Skip();
}

void MainDialog::OnCharFood( wxKeyEvent& event )
{
    if(!deleteGridRow(event.GetKeyCode(),m_gridFood))
        event.Skip();
}

void MainDialog::OnCharLocations( wxKeyEvent& event )
{
    if(!deleteGridRow(event.GetKeyCode(),m_gridLocations))
        event.Skip();
}

void MainDialog::OnCharUnits( wxKeyEvent& event )
{
    if(!deleteGridRow(event.GetKeyCode(),m_gridUnits))
        event.Skip();
}

void MainDialog::OnGridCellLeftClickUnits( wxGridEvent& event )
{
    lastRowSelectedUnits = event.GetRow();
    lastColSelectedUnits = event.GetCol();
    event.Skip();
}

void MainDialog::OnGridCellLeftClickLocations( wxGridEvent& event )
{
    lastRowSelectedLocations = event.GetRow();
    lastColSelectedLocations = event.GetCol();
    event.Skip();
}

bool MainDialog::deleteGridRow(int key, wxGrid* grid)
{
    if(key != WXK_DELETE) return false;

    int* lastRow = 0;
    int col;

    if(grid == this->m_gridMaterial)
    {
        lastRow = &lastRowSelectedMaterial;
        col = lastColSelectedMaterial;
    }
    else if(grid == this->m_gridFood)
    {
        lastRow = &lastRowSelectedFood;
        col = lastColSelectedFood;
    }
    else if(grid == this->m_gridUnits)
    {
        lastRow = &lastRowSelectedUnits;
        col = 0;
    }
    else if(grid == this->m_gridLocations)
    {
        lastRow = &lastRowSelectedLocations;
        col = lastColSelectedLocations;
    }

    if( grid->GetNumberRows() > 0 && lastRow > 0)
    {
        grid->DeleteRows(*lastRow);

        if(*lastRow == grid->GetNumberRows())
            *lastRow = (*lastRow)-1;

        grid->SetGridCursor(*lastRow,col);
        return true;
    }
    return false;
}

void MainDialog::OnGridCellChangeUnits( wxGridEvent& event )
{
    wxString str = this->m_gridUnits->GetCellValue(event.GetRow(),event.GetCol());

    renameMaterialAndFood(unit,0, str);
}

void MainDialog::OnGridCellChangeLocations( wxGridEvent& event )
{
    int i = event.GetCol();
    wxString str = this->m_gridLocations->GetCellValue(event.GetRow(),event.GetCol());

    switch(i)
    {
    case 0:
        renameMaterialAndFood(location1,0, str);
        break;
    case 1:
        renameMaterialAndFood(location2,1, str);
        break;
    case 2:
        renameMaterialAndFood(location3,2, str);
        break;
    case 3:
        renameMaterialAndFood(location4,3, str);
        break;
    case 4:
        renameMaterialAndFood(location5,4, str);
        break;
    case 5:
        renameMaterialAndFood(location6,5, str);
        break;
    }
}

void MainDialog::renameMaterialAndFood(wxArrayString& arr, int col, wxString str)
{
    arr.Clear();
    if(arr != this->unit)
    {
        for(int i = 0; i < this->m_gridLocations->GetNumberRows(); i++)
            if(this->m_gridLocations->GetCellValue(i,col) != wxEmptyString)
                arr.Add(this->m_gridLocations->GetCellValue(i,col));
        arr.Add(_T(""));
    }
    else
    {
        for(int i = 0; i < this->m_gridUnits->GetNumberRows(); i++)
            if(this->m_gridUnits->GetCellValue(i,0) != wxEmptyString)
                arr.Add(this->m_gridUnits->GetCellValue(i,0));
        col = UNIT-LOC1;
    }

    for(int i = 0; i < this->m_gridMaterial->GetNumberRows(); i++)
    {
        if(this->m_gridMaterial->GetCellValue(i,col+LOC1) == oldCellValue)
            this->m_gridMaterial->SetCellValue(i,col+LOC1,str);

        this->m_gridMaterial->SetCellEditor(i,col+LOC1,new wxGridCellChoiceEditor(arr,true));
    }

    for(int i = 0; i < this->m_gridFood->GetNumberRows(); i++)
    {
        if(this->m_gridFood->GetCellValue(i,col+LOC1) == oldCellValue)
            this->m_gridFood->SetCellValue(i,col+LOC1,str);

        this->m_gridFood->SetCellEditor(i,col+LOC1,new wxGridCellChoiceEditor(arr,true));
    }

    this->Refresh();
}

void MainDialog::onEditorShownUnits( wxGridEvent& event )
{
    this->oldCellValue = this->m_gridUnits->GetCellValue(event.GetRow(),event.GetCol());
}

void MainDialog::onEditorShownLocations( wxGridEvent& event )
{
    this->oldCellValue = this->m_gridLocations->GetCellValue(event.GetRow(),event.GetCol());
}

void MainDialog::OnTextMaterial( wxCommandEvent& event )
{
    if(searchStringCountMaterial > event.GetString().size())
        resetRowHeight(m_gridMaterial);
    searchItem(m_gridMaterial,event.GetString());
    searchStringCountMaterial = event.GetString().size();
}
void MainDialog::OnTextFood( wxCommandEvent& event )
{
    if(searchStringCountFood > event.GetString().size())
        resetRowHeight(m_gridFood);
    searchItem(m_gridFood,event.GetString());
    searchStringCountFood = event.GetString().size();
}

void MainDialog::searchItem(wxGrid* grid, wxString str)
{
    wxString str1 = str.MakeUpper();
    int rows = grid->GetNumberRows();

    for(int i = 0; i < rows; i++)
    {
        wxString s = grid->GetCellValue(i,TEXT).MakeUpper();
        wxStringTokenizer tkz(str1,_T(" "));

//      int c = tkz.CountTokens();
        while(tkz.HasMoreTokens())
        {
            wxString t = tkz.GetNextToken();
            if(!s.Contains(t))
            {
                grid->SetRowMinimalAcceptableHeight(0);
                grid->SetRowMinimalHeight(i,0);
                grid->SetRowSize(i,0);
                break;
            }
        }
    }
    grid->Refresh();
}

void MainDialog::resetRowHeight(wxGrid* grid)
{
    for(int i = 0; i < grid->GetNumberRows(); i++)
        grid->SetRowSize(i,20);
}

int MainDialog::addLineFood()
{
    combo  = new wxGridCellChoiceEditor(location1,true);
    combo1 = new wxGridCellChoiceEditor(location2,true);
    combo2 = new wxGridCellChoiceEditor(location3,true);
    combo3 = new wxGridCellChoiceEditor(location4,true);
    combo4 = new wxGridCellChoiceEditor(location5,true);
    combo5 = new wxGridCellChoiceEditor(location6,true);
    comboUnit = new wxGridCellChoiceEditor(unit,true);
    comboPriority = new wxGridCellChoiceEditor(prioritystr,true);

    boolEditor = new wxGridCellBoolEditor();
    if(!pPlugin->buyNo)
        boolEditor->UseStringValues(_("Yes"));
    else
        boolEditor->UseStringValues(_("Yes"),_("No"));

    int lastRow = this->m_gridFood->GetNumberRows();
    this->m_gridFood->AppendRows();

    this->m_gridFood->SetCellEditor(lastRow,BUY,boolEditor);
    this->m_gridFood->SetCellEditor(lastRow,PRIORITY,comboPriority);
    this->m_gridFood->SetCellEditor(lastRow,UNIT,comboUnit);
    this->m_gridFood->SetCellEditor(lastRow,LOC1,combo);
    this->m_gridFood->SetCellEditor(lastRow,LOC2,combo1);
    this->m_gridFood->SetCellEditor(lastRow,LOC3,combo2);
    this->m_gridFood->SetCellEditor(lastRow,LOC4,combo3);
    this->m_gridFood->SetCellEditor(lastRow,LOC5,combo4);
    this->m_gridFood->SetCellEditor(lastRow,LOC6,combo5);

    lastRow = this->m_gridFood->GetNumberRows()-1;

    this->m_gridFood->SetCellAlignment(lastRow,BUY,wxALIGN_CENTER,wxALIGN_CENTER);
    this->m_gridFood->SetCellAlignment(lastRow,PRIORITY,wxALIGN_CENTER,wxALIGN_CENTER);
    this->m_gridFood->SetCellAlignment(lastRow,QUOTA,wxALIGN_RIGHT,wxALIGN_RIGHT);
    this->m_gridFood->SetCellAlignment(lastRow,ACTUELL,wxALIGN_RIGHT,wxALIGN_RIGHT);
    this->m_gridFood->SetCellAlignment(lastRow,TOBUY,wxALIGN_RIGHT,wxALIGN_RIGHT);

    return lastRow;
}

int MainDialog::addLineMaterial()
{
    combo  = new wxGridCellChoiceEditor(location1,1);
    combo1 = new wxGridCellChoiceEditor(location2,1);
    combo2 = new wxGridCellChoiceEditor(location3,1);
    combo3 = new wxGridCellChoiceEditor(location4,1);
    combo4 = new wxGridCellChoiceEditor(location5,1);
    combo5 = new wxGridCellChoiceEditor(location6,1);
    comboUnit = new wxGridCellChoiceEditor(unit,1);
    boolEditor = new wxGridCellBoolEditor();
    comboPriority = new wxGridCellChoiceEditor(prioritystr,1);

    if(!pPlugin->buyNo)
        boolEditor->UseStringValues(_("Yes"));
    else
        boolEditor->UseStringValues(_("Yes"),_("No"));

    int lastRow = this->m_gridMaterial->GetNumberRows();
    this->m_gridMaterial->AppendRows();

    this->m_gridMaterial->SetCellEditor(lastRow,BUY,boolEditor);
    this->m_gridMaterial->SetCellEditor(lastRow,PRIORITY,comboPriority);
    this->m_gridMaterial->SetCellEditor(lastRow,UNIT,comboUnit);
    this->m_gridMaterial->SetCellEditor(lastRow,LOC1,combo);
    this->m_gridMaterial->SetCellEditor(lastRow,LOC2,combo1);
    this->m_gridMaterial->SetCellEditor(lastRow,LOC3,combo2);
    this->m_gridMaterial->SetCellEditor(lastRow,LOC4,combo3);
    this->m_gridMaterial->SetCellEditor(lastRow,LOC5,combo4);
    this->m_gridMaterial->SetCellEditor(lastRow,LOC6,combo5);

    lastRow = this->m_gridMaterial->GetNumberRows()-1;

    this->m_gridMaterial->SetCellAlignment(lastRow,BUY,wxALIGN_CENTER,wxALIGN_CENTER);
    this->m_gridMaterial->SetCellAlignment(lastRow,PRIORITY,wxALIGN_CENTER,wxALIGN_CENTER);
    this->m_gridMaterial->SetCellAlignment(lastRow,QUOTA,wxALIGN_RIGHT,wxALIGN_RIGHT);
    this->m_gridMaterial->SetCellAlignment(lastRow,ACTUELL,wxALIGN_RIGHT,wxALIGN_RIGHT);
    this->m_gridMaterial->SetCellAlignment(lastRow,TOBUY,wxALIGN_RIGHT,wxALIGN_RIGHT);

    return lastRow;
}

void MainDialog::saveData()
{
    this->m_buttonaddLineMaterial->SetFocus();
    TiXmlDocument doc;
    TiXmlComment * comment;
    const char* s;
    TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "UTF-8", "" );
    doc.LinkEndChild( decl );

    TiXmlElement * root = new TiXmlElement("FindItData");
    doc.LinkEndChild( root );

////////// Locations ///////////
    comment = new TiXmlComment();
    s= " Locations-Grid ";
    comment->SetValue(s);
    root->LinkEndChild( comment );

    TiXmlElement * node = new TiXmlElement( "LocationsColumnWidth" );
    root->LinkEndChild( node );

    TiXmlElement * node1 = new TiXmlElement( "Locations" );
    node->LinkEndChild( node1 );

    for(int i = 0; i < this->m_gridLocations->GetNumberCols(); i++)
        node1->SetAttribute(wxString::Format(wxT("c%d"), (int)i).mb_str(), this->m_gridLocations->GetColSize(i));

    comment = new TiXmlComment();
    s=" Data for Locations-Grid ";
    comment->SetValue(s);
    root->LinkEndChild( comment );

    node = new TiXmlElement( "LocationsRowData" );
    root->LinkEndChild( node );


    for( int row = 0; row < this->m_gridLocations->GetNumberRows(); row++)
    {
        node1 = new TiXmlElement( "Data" );
        node->LinkEndChild( node1 );

        for(int col = 0; col < this->m_gridLocations->GetNumberCols(); col++)
            node1->SetAttribute(wxString::Format(wxT("c%d"), (int)col).mb_str(), this->m_gridLocations->GetCellValue(row,col).mb_str());
    }

////////// Units ///////////
    comment = new TiXmlComment();
    s=" Units-Grid ";
    comment->SetValue(s);
    root->LinkEndChild( comment );

    node = new TiXmlElement( "UnitsColumnWidth" );
    root->LinkEndChild( node );

    node1 = new TiXmlElement( "Units" );
    node->LinkEndChild( node1 );

    for(int i = 0; i < this->m_gridUnits->GetNumberCols(); i++)
        node1->SetAttribute(wxString::Format(wxT("c%d"), (int)i).mb_str(), this->m_gridUnits->GetColSize(i));

    comment = new TiXmlComment();
    s=" Data for Units-Grid ";
    comment->SetValue(s);
    root->LinkEndChild( comment );

    node = new TiXmlElement( "UnitsRowData" );
    root->LinkEndChild( node );


    for( int row = 0; row < this->m_gridUnits->GetNumberRows(); row++)
    {
        node1 = new TiXmlElement( "Data" );
        node->LinkEndChild( node1 );
        node1->SetAttribute("c0",(const char*)m_gridUnits->GetCellValue(row,0).mb_str());
    }
/////////// Material ////////////
    comment = new TiXmlComment();
    s=" Material-Grid ";
    comment->SetValue(s);
    root->LinkEndChild( comment );

    node = new TiXmlElement( "MaterialColumnWidth" );
    root->LinkEndChild( node );

    node1 = new TiXmlElement( "Material" );
    node->LinkEndChild( node1 );

    for(int i = 0; i < this->m_gridMaterial->GetNumberCols(); i++)
        node1->SetAttribute(wxString::Format(wxT("c%d"), (int)i).mb_str(), this->m_gridMaterial->GetColSize(i));

    comment = new TiXmlComment();
    s=" Data for Material-Grid ";
    comment->SetValue(s);
    root->LinkEndChild( comment );

    node = new TiXmlElement( "MaterialRowData" );
    root->LinkEndChild( node );


    for( int row = 0; row < this->m_gridMaterial->GetNumberRows(); row++)
    {
        node1 = new TiXmlElement( "Data" );
        node->LinkEndChild( node1 );

        for(int col = 0; col < this->m_gridMaterial->GetNumberCols(); col++)
            node1->SetAttribute(wxString::Format(wxT("c%d"), (int)col).mb_str(), this->m_gridMaterial->GetCellValue(row,col).mb_str());
    }

/////////// Food ////////////
    comment = new TiXmlComment();
    s=" Food-Grid ";
    comment->SetValue(s);
    root->LinkEndChild( comment );

    node = new TiXmlElement( "ProvisionsColumnWidth" );
    root->LinkEndChild( node );

    node1 = new TiXmlElement( "Provisions" );
    node->LinkEndChild( node1 );

    for(int i = 0; i < this->m_gridFood->GetNumberCols(); i++)
        node1->SetAttribute(wxString::Format(wxT("c%d"), (int)i).mb_str(), this->m_gridFood->GetColSize(i));

    comment = new TiXmlComment();
    s=" Data for Provisions-Grid ";
    comment->SetValue(s);
    root->LinkEndChild( comment );

    node = new TiXmlElement( "ProvisionsRowData" );
    root->LinkEndChild( node );


    for( int row = 0; row < this->m_gridFood->GetNumberRows(); row++)
    {
        node1 = new TiXmlElement( "Data" );
        node->LinkEndChild( node1 );

        for(int col = 0; col < this->m_gridFood->GetNumberCols(); col++)
            node1->SetAttribute(wxString::Format(wxT("c%d"), (int)col).mb_str(), this->m_gridFood->GetCellValue(row,col).mb_str());
    }
    wxString xml = pHome_Locn;
    xml += _T("findit.xml");
    doc.SaveFile(xml.mb_str());
}

void MainDialog::loadData()
{
    wxString xml = pHome_Locn;
    xml += _T("findit.xml");
    TiXmlDocument doc(xml.mb_str());

    if (!doc.LoadFile(TIXML_ENCODING_LEGACY)) return;

    TiXmlHandle hDoc(&doc);
    TiXmlElement* pElem;
    TiXmlHandle hRoot(0);

    pElem=hDoc.FirstChildElement().Element();
    if (!pElem) return;
    hRoot=TiXmlHandle(pElem);

/////////// Locations //////////////
    TiXmlElement* pnode  =  hRoot.FirstChild( "LocationsColumnWidth" ).FirstChild().Element();

    int colWidth;
    for( ; pnode; pnode=pnode->NextSiblingElement())
    {
        for(int i = 0; i < this->m_gridLocations->GetNumberCols(); i++)
        {
            pnode->QueryIntAttribute(wxString::Format(_T("c%i"),i).mb_str(), &colWidth);
            this->m_gridLocations->SetColSize(i,colWidth);
        }
    }

    pnode  =  hRoot.FirstChild( "LocationsRowData" ).FirstChild().Element();

    wxString data;
    int lastRow;
    for( ; pnode; pnode=pnode->NextSiblingElement())
    {
        this->m_gridLocations->AppendRows();
        lastRow = this->m_gridLocations->GetNumberRows()-1;

        for(int i = 0; i < this->m_gridLocations->GetNumberCols(); i++)
        {

            data = wxString(pnode->Attribute(wxString::Format(_T("c%i"),i).mb_str()),wxConvUTF8);
            this->m_gridLocations->SetCellValue(lastRow,i,data);
            switch(i)
            {
            case 0:
                if(!data.IsEmpty()) location1.Add(data);
                break;
            case 1:
                if(!data.IsEmpty()) location2.Add(data);
                break;
            case 2:
                if(!data.IsEmpty()) location3.Add(data);
                break;
            case 3:
                if(!data.IsEmpty()) location4.Add(data);
                break;
            case 4:
                if(!data.IsEmpty()) location5.Add(data);
                break;
            case 5:
                if(!data.IsEmpty()) location6.Add(data);
                break;
            }
        }
    }
/////////// Units //////////////
    pnode  =  hRoot.FirstChild( "UnitsColumnWidth" ).FirstChild().Element();

    pnode->QueryIntAttribute("c0", &colWidth);
    this->m_gridUnits->SetColSize(0,colWidth);

    pnode  =  hRoot.FirstChild( "UnitsRowData" ).FirstChild().Element();

    for( ; pnode; pnode=pnode->NextSiblingElement())
    {
        this->m_gridUnits->AppendRows();
        lastRow = this->m_gridUnits->GetNumberRows()-1;

        data = wxString(pnode->Attribute("c0"),wxConvUTF8);
        this->m_gridUnits->SetCellValue(lastRow,0,data);
        if(!data.IsEmpty()) unit.Add(data);
    }

/////////// Material //////////////
    pnode  =  hRoot.FirstChild( "MaterialColumnWidth" ).FirstChild().Element();

    for( ; pnode; pnode=pnode->NextSiblingElement())
    {
        for(int i = 0; i < this->m_gridMaterial->GetNumberCols(); i++)
        {
            pnode->QueryIntAttribute(wxString::Format(_T("c%i"),i).mb_str(), &colWidth);
            this->m_gridMaterial->SetColSize(i,colWidth);
        }
    }

    pnode  =  hRoot.FirstChild( "MaterialRowData" ).FirstChild().Element();

    for( ; pnode; pnode=pnode->NextSiblingElement())
    {
        lastRow = this->addLineMaterial();

        for(int i = 0; i < this->m_gridMaterial->GetNumberCols(); i++)
        {
            if(i == BUY)
            {
                data = wxString(pnode->Attribute(wxString::Format(_T("c%i"),i).mb_str()),wxConvUTF8);
                if(pPlugin->buyNo)
                {
                    if(data == _T(""))
                        this->m_gridMaterial->SetCellValue(lastRow,BUY,_("No"));
                    else
                        this->m_gridMaterial->SetCellValue(lastRow,BUY,data);
                    continue;
                }
                else
                {
                    if(data == _("No"))
                        this->m_gridMaterial->SetCellValue(lastRow,BUY,_T(""));
                    else
                        this->m_gridMaterial->SetCellValue(lastRow,BUY,data);
                    continue;
                }
            }

            if(i != TOBUY)
            {
                data = wxString(pnode->Attribute(wxString::Format(_T("c%i"),i).mb_str()),wxConvUTF8);
                this->m_gridMaterial->SetCellValue(lastRow,i,data);
            }
        }
    }

/////////// Provisions //////////////
    pnode  =  hRoot.FirstChild( "ProvisionsColumnWidth" ).FirstChild().Element();

    for( ; pnode; pnode=pnode->NextSiblingElement())
    {
        for(int i = 0; i < this->m_gridFood->GetNumberCols(); i++)
        {
            pnode->QueryIntAttribute(wxString::Format(_T("c%i"),i).mb_str(), &colWidth);
            this->m_gridFood->SetColSize(i,colWidth);
        }
    }

    pnode  =  hRoot.FirstChild( "ProvisionsRowData" ).FirstChild().Element();

    for( ; pnode; pnode=pnode->NextSiblingElement())
    {
        lastRow = this->addLineFood();

        for(int i = 0; i < this->m_gridFood->GetNumberCols(); i++)
        {
            if(i == BUY)
            {
                data = wxString(pnode->Attribute(wxString::Format(_T("c%i"),i).mb_str()),wxConvUTF8);
                if(pPlugin->buyNo)
                {
                    if(data == _T(""))
                        this->m_gridFood->SetCellValue(lastRow,BUY,_("No"));
                    else
                        this->m_gridFood->SetCellValue(lastRow,BUY,data);
                    continue;
                }
                else
                {
                    if(data == _("No"))
                        this->m_gridFood->SetCellValue(lastRow,BUY,_T(""));
                    else
                        this->m_gridFood->SetCellValue(lastRow,BUY,data);
                    continue;
                }
            }
            if(i != TOBUY)
            {
                data = wxString(pnode->Attribute(wxString::Format(_T("c%i"),i).mb_str()),wxConvUTF8);
                this->m_gridFood->SetCellValue(lastRow,i,data);
            }
        }
    }

    for(int row = 0; row < this->m_gridMaterial->GetNumberRows(); row++)
        for(int col = QUOTA; col < UNIT; col++)
        {
            int quota = wxAtoi(m_gridMaterial->GetCellValue(row,QUOTA));
            int actuell = wxAtoi(m_gridMaterial->GetCellValue(row,ACTUELL));
            if(actuell < quota)
            {
                int diff = quota - actuell;
                this->m_gridMaterial->SetCellValue(row,TOBUY,wxString::Format(_("%i"),diff));
                this->m_gridMaterial->SetCellValue(row,BUY,_("Yes"));
            }
            else
            {
                if(pPlugin->toBuyZero)
                    this->m_gridMaterial->SetCellValue(row,TOBUY,_T("0"));
                if(pPlugin->buyNo)
                    this->m_gridMaterial->SetCellValue(row,BUY,_("No"));
                else
                    this->m_gridMaterial->SetCellValue(row,BUY,_T(""));
            }
        }

    for(int row = 0; row < this->m_gridFood->GetNumberRows(); row++)
        for(int col = QUOTA; col < UNIT; col++)
        {
            int quota = wxAtoi(m_gridFood->GetCellValue(row,QUOTA));
            int actuell = wxAtoi(m_gridFood->GetCellValue(row,ACTUELL));
            if(actuell < quota)
            {
                int diff = quota - actuell;
                this->m_gridFood->SetCellValue(row,TOBUY,wxString::Format(_("%i"),diff));
                this->m_gridFood->SetCellValue(row,BUY,_("Yes"));
            }
            else
            {
                if(pPlugin->toBuyZero)
                    this->m_gridFood->SetCellValue(row,TOBUY,_T("0"));
                if(pPlugin->buyNo)
                    this->m_gridFood->SetCellValue(row,BUY,_("No"));
                else
                    this->m_gridFood->SetCellValue(row,BUY,_T(""));
            }
        }
}

//////////////////////////// myGridStringTable /////////


WX_DEFINE_OBJARRAY(myGridStringArray)

//IMPLEMENT_DYNAMIC_CLASS( myGridStringTable, wxGridTableBase )

myGridStringTable::myGridStringTable()
    : wxGridTableBase()
{
}

myGridStringTable::myGridStringTable( int numRows, int numCols )
    : wxGridTableBase()
{
    m_data.Alloc( numRows );

    wxArrayString sa;
    sa.Alloc( numCols );
    sa.Add( wxEmptyString, numCols );

    m_data.Add( sa, numRows );
}

myGridStringTable::~myGridStringTable()
{
}

int myGridStringTable::GetNumberRows()
{
    return m_data.GetCount();
}

int myGridStringTable::GetNumberCols()
{
    if ( m_data.GetCount() > 0 )
        return m_data[0].GetCount();
    else
        return 0;
}

wxString myGridStringTable::GetValue( int row, int col )
{
    wxCHECK_MSG( (row < GetNumberRows()) && (col < GetNumberCols()),
                 wxEmptyString,
                 _T("invalid row or column index in myGridStringTable") );

    return m_data[row][col];
}

void myGridStringTable::SetValue( int row, int col, const wxString& value )
{
    wxCHECK_RET( (row < GetNumberRows()) && (col < GetNumberCols()),
                 _T("invalid row or column index in myGridStringTable") );

    m_data[row][col] = value;
}

bool myGridStringTable::IsEmptyCell( int row, int col )
{
    wxCHECK_MSG( (row < GetNumberRows()) && (col < GetNumberCols()),
                 true,
                 _T("invalid row or column index in myGridStringTable") );

    return (m_data[row][col] == wxEmptyString);
}

void myGridStringTable::Clear()
{
    int row, col;
    int numRows, numCols;

    numRows = m_data.GetCount();
    if ( numRows > 0 )
    {
        numCols = m_data[0].GetCount();

        for ( row = 0; row < numRows; row++ )
        {
            for ( col = 0; col < numCols; col++ )
            {
                m_data[row][col] = wxEmptyString;
            }
        }
    }
}

bool myGridStringTable::InsertRows( size_t pos, size_t numRows )
{
    size_t curNumRows = m_data.GetCount();
    size_t curNumCols = ( curNumRows > 0 ? m_data[0].GetCount() :
                          ( GetView() ? GetView()->GetNumberCols() : 0 ) );

    if ( pos >= curNumRows )
    {
        return AppendRows( numRows );
    }

    wxArrayString sa;
    sa.Alloc( curNumCols );
    sa.Add( wxEmptyString, curNumCols );
    m_data.Insert( sa, pos, numRows );

    if ( GetView() )
    {
        wxGridTableMessage msg( this,
                                wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
                                pos,
                                numRows );

        GetView()->ProcessTableMessage( msg );
    }

    return true;
}

bool myGridStringTable::AppendRows( size_t numRows )
{
    size_t curNumRows = m_data.GetCount();
    size_t curNumCols = ( curNumRows > 0
                          ? m_data[0].GetCount()
                          : ( GetView() ? GetView()->GetNumberCols() : 0 ) );

    wxArrayString sa;
    if ( curNumCols > 0 )
    {
        sa.Alloc( curNumCols );
        sa.Add( wxEmptyString, curNumCols );
    }

    m_data.Add( sa, numRows );

    if ( GetView() )
    {
        wxGridTableMessage msg( this,
                                wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
                                numRows );

        GetView()->ProcessTableMessage( msg );
    }

    return true;
}

bool myGridStringTable::DeleteRows( size_t pos, size_t numRows )
{
    size_t curNumRows = m_data.GetCount();

    if ( pos >= curNumRows )
    {
        wxFAIL_MSG( wxString::Format
                    (
                        wxT("Called myGridStringTable::DeleteRows(pos=%lu, N=%lu)\nPos value is invalid for present table with %lu rows"),
                        (unsigned long)pos,
                        (unsigned long)numRows,
                        (unsigned long)curNumRows
                    ) );

        return false;
    }

    if ( numRows > curNumRows - pos )
    {
        numRows = curNumRows - pos;
    }

    if ( numRows >= curNumRows )
    {
        m_data.Clear();
    }
    else
    {
        m_data.RemoveAt( pos, numRows );
    }

    if ( GetView() )
    {
        wxGridTableMessage msg( this,
                                wxGRIDTABLE_NOTIFY_ROWS_DELETED,
                                pos,
                                numRows );

        GetView()->ProcessTableMessage( msg );
    }

    return true;
}

bool myGridStringTable::InsertCols( size_t pos, size_t numCols )
{
    size_t row, col;

    size_t curNumRows = m_data.GetCount();
    size_t curNumCols = ( curNumRows > 0
                          ? m_data[0].GetCount()
                          : ( GetView() ? GetView()->GetNumberCols() : 0 ) );

    if ( pos >= curNumCols )
    {
        return AppendCols( numCols );
    }

    if ( !m_colLabels.IsEmpty() )
    {
        m_colLabels.Insert( wxEmptyString, pos, numCols );

        size_t i;
        for ( i = pos; i < pos + numCols; i++ )
            m_colLabels[i] = wxGridTableBase::GetColLabelValue( i );
    }

    for ( row = 0; row < curNumRows; row++ )
    {
        for ( col = pos; col < pos + numCols; col++ )
        {
            m_data[row].Insert( wxEmptyString, col );
        }
    }

    if ( GetView() )
    {
        wxGridTableMessage msg( this,
                                wxGRIDTABLE_NOTIFY_COLS_INSERTED,
                                pos,
                                numCols );

        GetView()->ProcessTableMessage( msg );
    }

    return true;
}

bool myGridStringTable::AppendCols( size_t numCols )
{
    size_t row;

    size_t curNumRows = m_data.GetCount();

#if 0
    if ( !curNumRows )
    {
        // TODO: something better than this ?
        //
        wxFAIL_MSG( wxT("Unable to append cols to a grid table with no rows.\nCall AppendRows() first") );
        return false;
    }
#endif

    for ( row = 0; row < curNumRows; row++ )
    {
        m_data[row].Add( wxEmptyString, numCols );
    }

    if ( GetView() )
    {
        wxGridTableMessage msg( this,
                                wxGRIDTABLE_NOTIFY_COLS_APPENDED,
                                numCols );

        GetView()->ProcessTableMessage( msg );
    }

    return true;
}

bool myGridStringTable::DeleteCols( size_t pos, size_t numCols )
{
    size_t row;

    size_t curNumRows = m_data.GetCount();
    size_t curNumCols = ( curNumRows > 0 ? m_data[0].GetCount() :
                          ( GetView() ? GetView()->GetNumberCols() : 0 ) );

    if ( pos >= curNumCols )
    {
        wxFAIL_MSG( wxString::Format
                    (
                        wxT("Called myGridStringTable::DeleteCols(pos=%lu, N=%lu)\nPos value is invalid for present table with %lu cols"),
                        (unsigned long)pos,
                        (unsigned long)numCols,
                        (unsigned long)curNumCols
                    ) );
        return false;
    }

    int colID;
    if ( GetView() )
        colID = GetView()->GetColAt( pos );
    else
        colID = pos;

    if ( numCols > curNumCols - colID )
    {
        numCols = curNumCols - colID;
    }

    if ( !m_colLabels.IsEmpty() )
    {
        // m_colLabels stores just as many elements as it needs, e.g. if only
        // the label of the first column had been set it would have only one
        // element and not numCols, so account for it
        int nToRm = m_colLabels.size() - colID;
        if ( nToRm > 0 )
            m_colLabels.RemoveAt( colID, nToRm );
    }

    for ( row = 0; row < curNumRows; row++ )
    {
        if ( numCols >= curNumCols )
        {
            m_data[row].Clear();
        }
        else
        {
            m_data[row].RemoveAt( colID, numCols );
        }
    }

    if ( GetView() )
    {
        wxGridTableMessage msg( this,
                                wxGRIDTABLE_NOTIFY_COLS_DELETED,
                                pos,
                                numCols );

        GetView()->ProcessTableMessage( msg );
    }

    return true;
}

wxString myGridStringTable::GetRowLabelValue( int row )
{
    if ( row > (int)(m_rowLabels.GetCount()) - 1 )
    {
        // using default label
        //
        return wxGridTableBase::GetRowLabelValue( row );
    }
    else
    {
        return m_rowLabels[row];
    }
}

wxString myGridStringTable::GetColLabelValue( int col )
{
    if ( col > (int)(m_colLabels.GetCount()) - 1 )
    {
        // using default label
        //
        return wxGridTableBase::GetColLabelValue( col );
    }
    else
    {
        return m_colLabels[col];
    }
}

void myGridStringTable::SetRowLabelValue( int row, const wxString& value )
{
    if ( row > (int)(m_rowLabels.GetCount()) - 1 )
    {
        int n = m_rowLabels.GetCount();
        int i;

        for ( i = n; i <= row; i++ )
        {
            m_rowLabels.Add( wxGridTableBase::GetRowLabelValue(i) );
        }
    }

    m_rowLabels[row] = value;
}

void myGridStringTable::SetColLabelValue( int col, const wxString& value )
{
    if ( col > (int)(m_colLabels.GetCount()) - 1 )
    {
        int n = m_colLabels.GetCount();
        int i;

        for ( i = n; i <= col; i++ )
        {
            m_colLabels.Add( wxGridTableBase::GetColLabelValue(i) );
        }
    }

    m_colLabels[col] = value;
}

/*
wxString myGridTable::GetTypeName(int row,int col)
{
    switch ( col )
    {
	case MainDialog::LOC1:
            return wxString::Format(_T("%s:all,MSW,GTK,other"), wxGRID_VALUE_CHOICE);
	case MainDialog::BUY:
            return wxGRID_VALUE_BOOL;
    default:
            return wxString::Format(_T("%s:80"), wxGRID_VALUE_STRING);
    }
}

int myGridTable::GetNumberRows()
{
    return m_data.GetCount();
}

int myGridTable::GetNumberCols()
{
    if ( m_data.GetCount() > 0 )
        return m_data[0].GetCount();
    else
        return 0;
}

bool myGridTable::IsEmptyCell( int WXUNUSED(row), int WXUNUSED(col) )
{
    return false;
}

wxString myGridTable::GetValue( int row, int col )
{
    const GridData& gd = dataGrid[row];

    switch ( col )
    {
	case MainDialog::BUY:
		return gd.buy ? _T("1") : _T("0");

	case MainDialog::PRIORITY:
		return gd.priority;

	case MainDialog::QUOTA:
		return gd.quota;

	case MainDialog::ACTUELL:
		return gd.actuell;

	case MainDialog::UNIT:
        return gd.unit;

	case MainDialog::TEXT:
		return gd.text;

	case MainDialog::LOC1:
		return gd.loc1;

	case MainDialog::LOC2:
		return gd.loc2;

	case MainDialog::LOC3:
		return gd.loc3;

	case MainDialog::LOC4:
		return gd.loc4;

	case MainDialog::LOC5:
		return gd.loc5;

	case MainDialog::LOC6:
		return gd.loc6;
    }

    return wxEmptyString;
}

void myGridTable::SetValue( int row, int col, const wxString& value )
{
    GridData& gd = dataGrid[row];

    switch ( col )
    {
	case MainDialog::BUY:
		gd.buy = (value == _T("1"))?true:false;
		break;
    }
}
*/

