/** @file wxtools.cpp wxWindows related tools. */

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
 #include <wx/wx.h>
#endif

#include "wxtools.h"
#include "hardware/OsSupp.h"


static int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices);


#define THUMB_SIZE 20		///< The size of the thumb, or visible portion of the scrollbar, in scroll units.
#define PAGE_SIZE 5		///< The size of the page size in scroll units. This is the number of units the scrollbar.
				///< will scroll when it is paged up or down.

/** Convert decimal value to scroll bar units. */
static inline int Decimal2Scroll(int decimal) 
{return 90-(decimal-10);}

/** Convert scroll bar units to decimal value. */
static inline int Scroll2Decimal(int scroll) 
{return 90-scroll+10;}


/** This method increments a given parameter. */
void SolveSpinUp(double & Value, wxTextCtrl *Txt_Ctrl, wxScrollBar *Scr)
{
wxString Str;
double Order,XOrder;

  if(Value==0) 
    {
    Value=0.1;
    }
  else
    {
    Order=log10(abs(Value));
    XOrder=floor(Order + 1e-9);    
    Value += 0.1*pow(10.0,XOrder) * sign(Value);
    /** increment values this way: 1 ... 9.9;10;11; ..... 98;99;100 */

    if(Scr)
      {
      Order-=XOrder;  //decimal value
      int ScrollVal = pow(10.0,1+Order)+1;
      if(ScrollVal>99) ScrollVal=10;
      Scr->SetScrollbar(Decimal2Scroll(ScrollVal),THUMB_SIZE,90+(THUMB_SIZE-1),PAGE_SIZE);
      }
    }
  
  if(Txt_Ctrl)
    {
    Str.Printf(wxT("%g"),Value);
    Txt_Ctrl->SetValue(Str);  
    }
}


/** This method decrements a given parameter. */
void SolveSpinDown(double & Value, wxTextCtrl *Txt_Ctrl, wxScrollBar *Scr)
{
double Order, XOrder;  

  if(Value==0) return;
    
  Order = log10(abs(Value));
  XOrder=floor(Order - 1e-9);            
  Value -= 0.1*pow(10.0,XOrder) * sign(Value);
     // decrement values this way: 100;99;98 ... ;11;10;9.9;9.8 ... 1.0
  if(Txt_Ctrl)
    {
    wxString Str;
    Str.Printf( wxT("%g"), Value);
    Txt_Ctrl->SetValue(Str);  
    }
  if(Scr)
    {
    Order-=XOrder;  //decimal value  
    int ScrollVal = pow(10.0,1+Order)-1;
    if(ScrollVal<10) ScrollVal=99;
    Scr->SetScrollbar(Decimal2Scroll(ScrollVal),THUMB_SIZE,90+(THUMB_SIZE-1),PAGE_SIZE);
    }
}


void UpdateScrollBar(double Value, wxScrollBar *Scr)
{
double Order, XOrder;  

  if(Value==0) return;
  if(Scr==NULL) return;
    
  Order = log10(abs(Value));
  XOrder=floor(Order - 1e-9);            
  
  Order-=XOrder;  //decimal value  
  int ScrollVal = pow(10.0,1+Order);  
  Scr->SetScrollbar(Decimal2Scroll(ScrollVal),THUMB_SIZE,90+(THUMB_SIZE-1),PAGE_SIZE);
}


void UpdateValue(wxScrollBar *Scr, double *Value)
{
double Order, XOrder;  
double ScrollVal;

  if(Value==NULL) return;
  if(*Value==0) return;
  if(Scr==NULL) return;
    
  Order = log10(abs(*Value));
  XOrder=floor(Order - 1e-9);            
  
  ScrollVal = Scroll2Decimal(Scr->GetThumbPosition());

  *Value = ScrollVal*pow(10.0,XOrder-1) * sign(*Value);
}


/** This procedure checks whether text control contains double value. */
double CheckDoubleTxt(wxTextCtrl* TxtVal)
{
wxString xStr;
double d;
wxColour CurrBg;

  if(TxtVal==NULL) return 0;
  xStr=TxtVal->GetValue();
  CurrBg=TxtVal->GetBackgroundColour();

  if(!xStr.ToDouble(&d))
     {
     MakeNaN(&d);
     TxtVal->SetBackgroundColour(wxColour(_T("RED")));
     if(CurrBg!=wxColour(_T("RED"))) TxtVal->Refresh();
     }
  else
     {
     TxtVal->SetBackgroundColour(wxNullColour);
     if(CurrBg==wxColour(_T("RED"))) TxtVal->Refresh();
     }  

  return d;
}


int wxGetSingleChoiceIndex( const wxString& message,
                            const wxString& caption,
			    int PreSelect,
                            int n, const wxString *choices,
                            wxWindow *parent,
                            int WXUNUSED(x), int WXUNUSED(y),
                            bool WXUNUSED(centre),
                            int WXUNUSED(width), int WXUNUSED(height) )
{
    wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
    if(PreSelect>=0)
      dialog.SetSelection(PreSelect);
    
    if ( dialog.ShowModal() == wxID_OK )
        PreSelect = dialog.GetSelection();
    else
        PreSelect = -1;

    return PreSelect;
}

int wxGetSingleChoiceIndex( const wxString& message,
                            const wxString& caption,
			    int PreSelect,
                            const wxArrayString& aChoices,
                            wxWindow *parent,
                            int x, int y,
                            bool centre,
                            int width, int height)
{
    wxString *choices;
    int n = ConvertWXArrayToC(aChoices, &choices);
    int res = wxGetSingleChoiceIndex(message, caption, PreSelect, n, choices, parent,
                                     x, y, centre, width, height);
    delete [] choices;

    return res;
}


int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices)
{
    size_t n = aChoices.GetCount();
    *choices = new wxString[n];

    for ( size_t i = 0; i < n; i++ )
    {
        (*choices)[i] = aChoices[i];
    }

    return n;
}