/*
 * File:	wx_dialg.cc
 * Purpose:	wxDialogBox and miscellaneous dialog functions
 * Author:	Julian Smart
 * Created:	1993
 * Updated:	August 1994
 * RCS_ID:      $Id: wx_dialg.cc,v 1.1 1994/08/14 21:59:17 edz Exp $
 * Copyright:	(c) 1993, AIAI, University of Edinburgh
 */

/* static const char sccsid[] = "%W% %G%"; */

#if !defined(_MSC_VER) && !defined(wx_wxh)
#define wx_wxh
#endif

#ifdef __WATCOMC__
#define INCLUDE_COMMDLG_H	1
#endif

#include "wx_dialg.h"
#include "wx_utils.h"
#include "wx_frame.h"
#include "wx_main.h"

#include "wx.h"
#pragma hdrstop
#include "wx_setup.h"
#include "wx_privt.h"

#if USE_COMMON_DIALOGS
#include <commdlg.h>
#endif

#if CTL3D
#include <ctl3d.h>
#endif

#if FAFA_LIB
#include "fafa.h"
#endif

#if !defined(APIENTRY)	// NT defines APIENTRY, 3.x not
#define APIENTRY far pascal
#endif
 
#ifdef WIN32
#define _EXPORT /**/
#else
#define _EXPORT _export
typedef signed short int SHORT ;
#endif
 
#if !defined(WIN32)	// 3.x uses FARPROC for dialogs
#define DLGPROC FARPROC
#endif

#define wxDIALOG_DEFAULT_X 300
#define wxDIALOG_DEFAULT_Y 300

// Lists to keep track of windows, so we can disable/enable them
// for modal dialogs
wxList wxModalDialogs;
wxList wxModelessWindows;  // Frames and modeless dialogs

class wxDialogWnd : public wxSubWnd
{
public:
  wxDialogWnd(wxWnd *parent, wxWindow *wx_win,
              int x, int y, int width, int height,
              char *dialog_template);

  // Handlers
  LONG DefWindowProc(UINT nMsg, UINT wParam, LONG lParam);
  BOOL ProcessMessage(MSG* pMsg);
  BOOL OnEraseBkgnd(HDC pDC);
  BOOL OnClose(void);
};

wxDialogWnd::wxDialogWnd(wxWnd *parent, wxWindow *wx_win,
              int x, int y, int width, int height,
              char *dialog_template):
  wxSubWnd(parent, NULL, wx_win, x, y, width, height, 0, dialog_template)
{
}

LONG wxDialogWnd::DefWindowProc(UINT nMsg, UINT wParam, LONG lParam)
{
  return ::DefWindowProc(handle, nMsg, wParam, lParam);
}

BOOL wxDialogWnd::ProcessMessage(MSG* pMsg)
{
  return ::IsDialogMessage(handle, pMsg);
}

BOOL wxDialogWnd::OnClose(void)
{
  if (wx_window)
  {
    if (wx_window->GetEventHandler()->OnClose())
    {
      ((wxDialogBox *)wx_window)->Show(FALSE);
      delete wx_window;
      return TRUE;
    } else return FALSE;
  }
  return FALSE;
}

BOOL wxDialogWnd::OnEraseBkgnd(HDC pDC)
{
  if (background_brush)
  {
    RECT rect;
    GetClientRect(handle, &rect);
    int mode = SetMapMode(pDC, MM_TEXT);
    FillRect(pDC, &rect, background_brush);
    SetMapMode(pDC, mode);
    return TRUE;
  }
  else return FALSE;
}

IMPLEMENT_DYNAMIC_CLASS(wxDialogBox, wxPanel)

wxDialogBox::wxDialogBox(void)
{
  window_parent = NULL;
  handle = NULL;
  modal = FALSE;
  is_show = FALSE;
  modal_showing = FALSE;
  has_child = FALSE ;

  hSpacing = PANEL_HSPACING;
  vSpacing = PANEL_VSPACING;
  
  initial_hspacing = hSpacing ;
  initial_vspacing = vSpacing ;

  current_hspacing = hSpacing ;
  current_vspacing = vSpacing ;
}

// Dialog box - like panel but doesn't need a frame, and is modal or
// non-modal
wxDialogBox::wxDialogBox(wxWindow *Parent, char *Title, Bool Modal, 
               int x, int y, int width, int height, long style, char *name):
  wxbDialogBox(Parent, Title, Modal, x, y, width, height, style, name)
{
  Create(Parent, Title, Modal, x, y, width, height, style, name);
}
  
Bool wxDialogBox::Create(wxWindow *Parent, char *Title, Bool Modal, 
                         int x, int y, int width, int height, long style, char *name)
{
  SetName(name);

  // Do anything that needs to be done in the generic base class
  wxbDialogBox::Create(Parent, Title, Modal, x, y, width, height, style, name);

  has_child = FALSE ;

  hSpacing = PANEL_HSPACING;
  vSpacing = PANEL_VSPACING;
  
  initial_hspacing = hSpacing ;
  initial_vspacing = vSpacing ;

  current_hspacing = hSpacing ;
  current_vspacing = vSpacing ;
  
  if (Parent) Parent->AddChild(this);
  window_parent = Parent;

  if (x < 0) x = wxDIALOG_DEFAULT_X;
  if (y < 0) y = wxDIALOG_DEFAULT_Y;

  wxWinType = wxTYPE_XWND;
  windowStyle = style;
  wxWnd *cparent = NULL;
  if (Parent)
    cparent = (wxWnd *)Parent->handle;

  is_show = FALSE;
  modal_showing = FALSE;

  if (width < 0)
    width = 500;
  if (height < 0)
    height = 500;

  // Allows creation of dialogs with & without captions under MSWindows
  wxDialogWnd *wnd;
  if(style & wxCAPTION){
    wnd = new wxDialogWnd(cparent, this, x, y, width, height,
                          "wxCaptionDialog");
  }
  else{
    wnd = new wxDialogWnd(cparent, this, x, y, width, height,
                          "wxNoCaptionDialog");
  }

  handle = (char *)wnd;
  SetWindowText(wnd->handle, Title);

  if (!Modal)
    wxModelessWindows.Append(this);

  wx_dc = new wxPanelDC (this);

  modal = Modal;
  return TRUE;
}

wxDialogBox::~wxDialogBox()
{
  wxWnd *wnd = (wxWnd *)handle;
  if (wnd && modal_showing)
    Show(FALSE);

  modal_showing = FALSE;
  if (wnd)
  {
    ShowWindow(wnd->handle, SW_HIDE);
  }
  if (!modal)
    wxModelessWindows.DeleteObject(this);
}

// By default, pressing escape quits the dialog
Bool wxDialogBox::OnCharHook(wxKeyEvent& event)
{
  if (handle)
  {
    if (event.keyCode == WXK_ESCAPE)
    {
      if (OnClose())
      {
        Show(FALSE);
        delete this;
      }
      return TRUE;
    }
  }
  return FALSE;
}

void wxDialogBox::Fit(void)
{
  wxPanel::Fit();
}

void wxDialogBox::Iconize(Bool iconize)
{
  // Windows dialog boxes can't be iconized
}

Bool wxDialogBox::Iconized(void)
{
  return FALSE;
}

void wxDialogBox::SetSize(int x, int y, int width, int height, int sizeFlags)
{
  wxWindow::SetSize(x, y, width, height);
}

void wxDialogBox::SetClientSize(int width, int height)
{
  wxWnd *wnd = (wxWnd *)handle;
  RECT rect;
  GetClientRect(wnd->handle, &rect);

  RECT rect2;
  GetWindowRect(wnd->handle, &rect2);

  // Find the difference between the entire window (title bar and all)
  // and the client area; add this to the new client size to move the
  // window
  int actual_width = rect2.right - rect2.left - rect.right + width;
  int actual_height = rect2.bottom - rect2.top - rect.bottom + height;

  MoveWindow(wnd->handle, rect2.left, rect2.top, actual_width, actual_height, TRUE);
  GetEventHandler()->OnSize(actual_width, actual_height);
}

void wxDialogBox::GetPosition(int *x, int *y)
{
  HWND hWnd = GetHWND();
  RECT rect;
  GetWindowRect(hWnd, &rect);

  *x = rect.left;
  *y = rect.top;
}

Bool wxDialogBox::IsShown(void)
{
  return is_show;
}

Bool wxDialogBox::Show(Bool show)
{
  is_show = show;
  wxWnd *dialog = (wxWnd *)handle;
  if (modal)
  {
    if (show)
    {
      if (modal_showing)
      {
        BringWindowToTop(dialog->handle);
        return TRUE;
      }
      
      modal_showing = TRUE;
      wxNode *node = wxModalDialogs.First();
      while (node)
      {
        wxDialogBox *box = (wxDialogBox *)node->Data();
        wxWnd *the_dialog = (wxWnd *)box->handle;
        if (box != this)
          EnableWindow(the_dialog->handle, FALSE);
        node = node->Next();
      }
      node = wxModelessWindows.First();
      while (node)
      {
        wxWindow *win = (wxWindow *)node->Data();
        wxWnd *wnd = (wxWnd *)win->handle;
        EnableWindow(wnd->handle, FALSE);
        node = node->Next();
      }

      ShowWindow(dialog->handle, SW_SHOW);
      EnableWindow(dialog->handle, TRUE);
      BringWindowToTop(dialog->handle);

      if (!wxModalDialogs.Member(this))
        wxModalDialogs.Append(this);

      MSG msg;
      while (modal_showing && GetMessage(&msg, NULL, 0, 0))
      {
        if (!IsDialogMessage(dialog->handle, &msg))
        {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
        }
      }
    }
    else
    {
      wxModalDialogs.DeleteObject(this);

      wxNode *first = wxModalDialogs.First();

      // If there's still a modal dialog active, we
      // enable it, else we enable all modeless windows
      if (first)
      {
        wxDialogBox *box = (wxDialogBox *)first->Data();
        HWND hwnd = box->GetHWND();
        if (box->winEnabled)
          EnableWindow(hwnd, TRUE);
        BringWindowToTop(dialog->handle);
      }
      else
      {
        wxNode *node = wxModelessWindows.First();
        while (node)
        {
          wxWindow *win = (wxWindow *)node->Data();
          HWND hwnd = win->GetHWND();
          // Only enable again if not user-disabled.
          if (win->winEnabled)
            EnableWindow(hwnd, TRUE);
          node = node->Next();
        }
      }
      // Try to highlight the correct window (the parent)
      HWND hWndParent = 0;
      if (GetParent())
      {
        hWndParent = GetParent()->GetHWND();
        if (hWndParent)
          ::BringWindowToTop(hWndParent);
      }
      ShowWindow(dialog->handle, SW_HIDE);
      modal_showing = FALSE;
    }
  }
  else
  {
    if (show)
    {
      ShowWindow(dialog->handle, SW_SHOW);
      BringWindowToTop(dialog->handle);
    }
    else
    {
      // Try to highlight the correct window (the parent)
      HWND hWndParent = 0;
      if (GetParent())
      {
        hWndParent = GetParent()->GetHWND();
        if (hWndParent)
          ::BringWindowToTop(hWndParent);
      }
      ShowWindow(dialog->handle, SW_HIDE);
    }
  }
  return TRUE;
}

void wxDialogBox::SetTitle(char *title)
{
  wxWnd *wnd = (wxWnd *)handle;
  SetWindowText(wnd->handle, title);
}

char *wxDialogBox::GetTitle(void)
{
  wxWnd *wnd = (wxWnd *)handle;
  GetWindowText(wnd->handle, wxBuffer, 1000);
  return wxBuffer;
}

/*
 * Common dialogs
 *
 */
 
// Pop up a message box
int wxMessageBox(char *message, char *caption, long type,
                 wxWindow *parent, int x, int y)
{
  if ((type & wxCENTRE) == wxCENTRE)
    return wxbMessageBox(message, caption, type, parent, x, y);
    
  HWND hWnd = 0;
  if (parent) hWnd = parent->GetHWND();
  unsigned int msStyle = MB_OK;
  if (type & wxYES_NO)
  {
    if (type & wxCANCEL)
      msStyle = MB_YESNOCANCEL;
    else
      msStyle = MB_YESNO;
  }
  if (type & wxOK)
  {
    if (type & wxCANCEL)
      msStyle = MB_OKCANCEL;
    else
      msStyle = MB_OK;
  }
  if (type & wxICON_EXCLAMATION)
    msStyle |= MB_ICONEXCLAMATION;
  else if (type & wxICON_HAND)
    msStyle |= MB_ICONHAND;
  else if (type & wxICON_INFORMATION)
    msStyle |= MB_ICONINFORMATION;
  else if (type & wxICON_QUESTION)
    msStyle |= MB_ICONQUESTION;

  if (hWnd)
    msStyle |= MB_APPLMODAL;
  else
    msStyle |= MB_TASKMODAL;
    
  int msAns = MessageBox(hWnd, (LPCSTR)message, (LPCSTR)caption, msStyle);
  int ans = wxOK;
  switch (msAns)
  {
    case IDCANCEL:
      ans = wxCANCEL;
      break;
    case IDOK:
      ans = wxOK;
      break;
    case IDYES:
      ans = wxYES;
      break;
    case IDNO:
      ans = wxNO;
      break;
  }
  return ans;
}

#if USE_COMMON_DIALOGS

// Crashes: removed for present - JACS Oct 94
// DISCOVERED WHY: according to the MS Knowledge Base,
// you must put it in the EXPORTS section of the .DEF file.
// Shouldn't _EXPORT do this? Anyway, it sounds rather
// like the reported error: not being able to access
// local variable because of wrong segment setting.
// Worth a try.
// OR -- more likely -- need to do MakeProcInstance in wxFileSelector
// to make it work properly.
#if 0    		 
unsigned int APIENTRY _EXPORT
  wxFileHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
#if FAFA_LIB
  switch(message)
  {
        case WM_ERASEBKGND:
        {
          RECT rect;
	  HDC pDC = (HDC)wParam ;
          GetClientRect(hWnd, &rect);
          int mode = SetMapMode(pDC, MM_TEXT);
          FillRect(pDC, &rect, brushFace);
          SetMapMode(pDC, mode);
          break;
        }
#ifdef WIN32
        case WM_CTLCOLORDLG:
	{
          return (unsigned int)brushFace ;
          break;
	}
        case WM_CTLCOLORBTN:
        case WM_CTLCOLORSTATIC:
	{
          HDC pDC = (HDC)wParam;
          SetTextColor(pDC,colorLabel) ;
          SetBkMode(pDC,TRANSPARENT) ;
          return (unsigned int)brushFace ;
          break;
	}
        case WM_CTLCOLOREDIT:
	{
          HDC pDC = (HDC)wParam;
          SetTextColor(pDC,colorLabel) ;
          return NULL ;
          break;
	}
#else
        case WM_CTLCOLOR:
        {
          int nCtlColor = (int)HIWORD(lParam);
          HDC pDC = (HDC)wParam;
	  switch(nCtlColor)
          {
          case CTLCOLOR_DLG:
            return (unsigned int)brushFace ;
          break ;
	  case CTLCOLOR_BTN:
	  case CTLCOLOR_STATIC:
	    // BUGBUG For some reason it crashes at this point,
	    // so I'm commenting out this whole hook.
            SetTextColor(pDC,colorLabel) ;
            SetBkMode(pDC,TRANSPARENT) ;
            return (unsigned int)brushFace ;
          break ;
	  case CTLCOLOR_EDIT:
            SetTextColor(pDC,colorLabel) ;
            return NULL ;
          break ;
          }
          break;
        }
#endif
  }
#endif
  return(FALSE) ; // Pass non processed messages to standard dialog box fct.
}
#endif
#endif
  // end USE_COMMON_DIALOGS

char *wxFileSelector(char *message,
                     char *default_path, char *default_filename, 
                     char *default_extension, char *wildcard, int flags,
                     wxWindow *parent, int x, int y)
{
#if !USE_COMMON_DIALOGS
  // Great file selector folks !!!
  return wxGetTextFromUser(message, "Enter filename", NULL, parent, x, y);
#else
  // Use extended version (below) NO!! This function is very buggy. (WAS very buggy.)
//  return wxFileSelectorEx(message, default_path, default_filename,
//        NULL, wildcard, flags, parent, x, y);

  if (x < 0) x = wxDIALOG_DEFAULT_X;
  if (y < 0) y = wxDIALOG_DEFAULT_Y;

  wxWnd *wnd = NULL;
  HWND hwnd = NULL;
  if (parent)
  {
    wnd = (wxWnd *)parent->handle;
    hwnd = wnd->handle;
  }
  static char file_buffer[400];

  if (default_filename)
    strcpy(file_buffer, default_filename);
  else file_buffer[0] = 0;

  char title_buffer[50];
  title_buffer[0] = 0;

  char filter_buffer[200];

  if (!wildcard)
    wildcard = "*.*";

/* Alejandro Sierra's wildcard modification

In wxFileSelector you can put, instead of a single wild_card, pairs of
strings separated by '|'. The first string is a description, and the
second is the wild card. You can put any number of pairs.

eg.  "description1 (*.ex1)|*.ex1|description2 (*.ex2)|*.ex2"

If you put a single wild card, it works as before my modification.
*/

// Here begin my changes (Alex)              ******************************
  if (wildcard)                               
  {
         if (!strchr(wildcard, '|'))         // No '|'s, I leave it as it was
                sprintf(filter_buffer, "Files (%s)|%s",wildcard, wildcard);
         else
                strcpy(filter_buffer, wildcard);

         int len = strlen(filter_buffer);

         for (int i = 0; i < len; i++)
                if (filter_buffer[i]=='|')
                  filter_buffer[i] = '\0';

         filter_buffer[len+1] = '\0';

  }
// Here end my changes (Alex)              ******************************
/* Now replaced by Alex's code above

  if (wildcard)
  {
    sprintf(filter_buffer, "Files (%s)", wildcard);
    int len1 = strlen(filter_buffer);
    int len2 = strlen(wildcard);

    filter_buffer[len1] = 0;
    int i;
    for (i = 0; i < len2; i++)
      filter_buffer[len1 + 1 + i] = wildcard[i];
    filter_buffer[len1 + 1 + len2] = 0;
    filter_buffer[len1 + 2 + len2] = 0;
  }
*/
  OPENFILENAME of;
  memset(&of, 0, sizeof(OPENFILENAME));

  of.lStructSize = sizeof(OPENFILENAME);
  of.hwndOwner = hwnd;

  if (wildcard)
  {
    of.lpstrFilter = (LPSTR)filter_buffer;
    of.nFilterIndex = 1L;
  }
  else
  {
    of.lpstrFilter = NULL;
    of.nFilterIndex = 0L;
  }
  of.lpstrCustomFilter = NULL;
  of.nMaxCustFilter = 0L;
  of.lpstrFile = file_buffer;
  of.nMaxFile = 400;
  of.lpstrFileTitle = title_buffer;
  of.nMaxFileTitle = 50;
  of.lpstrInitialDir = default_path;
  of.lpstrTitle = message;
  of.nFileOffset = 0;
  of.nFileExtension = 0;
  of.lpstrDefExt = default_extension;

  long msw_flags = 0;

  if (flags & wxOVERWRITE_PROMPT)
    msw_flags |= OFN_OVERWRITEPROMPT;
  if (flags & wxHIDE_READONLY)
    msw_flags |= OFN_HIDEREADONLY;
  of.Flags = msw_flags;
//  of.Flags = msw_flags|OFN_ENABLEHOOK;
//  of.lpfnHook = wxFileHook ;

  Bool success;
  if (flags & wxSAVE)
    success = GetSaveFileName(&of);
  else
    success = GetOpenFileName(&of);

//  DWORD error = CommDlgExtendedError();
  if (success)
    return file_buffer;
  else
    return NULL;
#endif
  // End USE_COMMON_DIALOGS
}

#if USE_COMMON_DIALOGS
/*
    wxFileSelector  modification (only for MS-Windows (yet) ) :


    char* wxFileSelectorEx( char* 	  title,               // = "Select a file"
						    char* 	  defaultDir,          // = NULL
						    char* 	  defaultFileName,     // = NULL
						    int*      defaultFilterIndex,  // = NULL
						    char*     filter,              // = "*.*"
                            int       flags,               // = 0
                            wxWindow* parent,              // = NULL
                            int       x,                   // = -1
                            int       y )                  // = -1

    wxFileSelectorEx is as wxFileSelector with little changes:

    The defaultFilterIndex is changed to int*,
    so You can get the selected filter.

    To the filename is automaticely added the selected
    extension if You type only the filename in the dialogbox.

    eg.  if filter is "Data (*.dat)|*.dat|Text (*.txt)|*.txt|All (*.*)|*.*"

    and you have selected: *.txt
    and you type 'hello' into the Filedialog,
    the filename is expanded to hello.txt.
    If you want explicitely save or load 'hello' as
    'hello' and not as 'hello.txt', You have to select *.*,
    or type 'hello.'  .

    So I use it in my Application:

void Open( void )
{
# ifdef wx_msw
    char tempList[] = "Daten (*.dat)|*.dat|Texte (*.txt)|*.txt|Alle (*.*)|*.*";
# else
    char tempList[] = "*.dat";  // <<== This also works under wx_msw  
# endif                                 

    static int fileDialogIndex = 1;

    char* tempName = wxFileSelector( "Open file",
                                     NULL,
                                     NULL,
                                     &fileDialogIndex,
                                     tempList,
                                     wxOPEN | wxHIDE_READONLY,
                                     NULL,
                                     20,
                                     20 );
}

Regards,
         Alfred

*/

# if __BORLANDC__
#   include <dir.h>  // for MAXPATH etc. ( Borland 3.1 ) 
# endif

# ifndef MAXPATH
# define MAXPATH   400   
# endif

# ifndef MAXDRIVE
# define MAXDRIVE  3
# endif

# ifndef MAXFILE 
# define MAXFILE   9
# endif

# ifndef MAXEXT
# define MAXEXT    5
# endif


char* wxFileSelectorEx( char* 	  title,               // = "Select a file"
			char* 	  defaultDir,          // = NULL
			char* 	  defaultFileName,     // = NULL
			int*      defaultFilterIndex,  // = NULL
			char*     filter,              // = "*.*"
                        int       flags,               // = 0
                        wxWindow* parent,              // = NULL
                        int       x,                   // = -1
                        int       y )                  // = -1

{
    if ( x < 0 ) { x = wxDIALOG_DEFAULT_X; }
    if ( y < 0 ) { y = wxDIALOG_DEFAULT_Y; }

    HWND  HWindow = ( parent ) ? ((wxWnd *)parent->handle)->handle : NULL;

	static char  fileNameBuffer [ MAXPATH ];		   // the file-name
	char         titleBuffer    [ MAXFILE+1+MAXEXT ];  // the file-name, without path

	*fileNameBuffer = '\0';
    *titleBuffer    = '\0';

	char* filterBuffer = NULL;
	char* extension    = NULL;

    long msw_flags = 0;
    if ( flags & wxHIDE_READONLY ) { msw_flags |= OFN_HIDEREADONLY; }


	OPENFILENAME of;
	memset(&of, 0, sizeof(OPENFILENAME));

    of.lpstrCustomFilter = NULL;   // system should not save custom filter
	of.nMaxCustFilter    = 0L;

	of.nFileOffset       = 0;      // 0-based pointer to filname in lpstFile
	of.nFileExtension    = 0;      // 0-based pointer to extension in lpstrFile
	of.lpstrDefExt       = NULL;   // no default extension

	of.lStructSize 		 = sizeof(OPENFILENAME);
	of.hwndOwner 		 = HWindow;
	of.lpstrTitle        = title;


	of.lpstrFileTitle    = titleBuffer;
	of.nMaxFileTitle     = MAXFILE + 1 + MAXEXT;	// Windows 3.0 and 3.1

	of.lpstrInitialDir   = defaultDir;

	of.Flags 			 = msw_flags;



    //=== Like Alejandro Sierra's wildcard modification >>===================
    /*
        In wxFileSelector you can put, instead of a single wild_card,
        pairs of strings separated by '|'.
        The first string is a description, and the
        second is the wild card. You can put any number of pairs.

        eg.  "description1 (*.ex1)|*.ex1|description2 (*.ex2)|*.ex2"

        If you put a single wild card, it works as before the modification.
    */
    //=======================================================================

	if ( !filter ) filter = "*.*";

	int filterBufferLen = 0;

	if ( !strchr( filter, '|' ) ) { 			// only one filter ==> default text:
		char buffText[] = "Files (%s)|%s";
		filterBufferLen = strlen( filter )*2 + strlen( buffText ) -4;
		filterBuffer    = new char[ filterBufferLen +2 ];

		if ( filterBuffer ) {
			sprintf( filterBuffer, buffText, filter, filter );
		}
	}
	else {                  					// more then one filter
		filterBufferLen = strlen( filter );
		filterBuffer    = new char[ filterBufferLen +2 ];

		if ( filterBuffer ) {
			strcpy( filterBuffer, filter );
	    }
	}

    if ( filterBuffer ) {  					    // Substituting '|' with '\0'
		for ( int i = 0; i < filterBufferLen; i++ ) {
			if ( filterBuffer[i] == '|' ) { filterBuffer[i] = '\0'; }
		}
	}

	filterBuffer[filterBufferLen+1] = '\0';

	of.lpstrFilter  = (LPSTR)filterBuffer;
	of.nFilterIndex = (defaultFilterIndex) ? *defaultFilterIndex : 1;



    //=== Setting defaultFileName >>=========================================

	if ( defaultFileName ) {
        strncpy( fileNameBuffer, defaultFileName, MAXPATH-1 );
	    fileNameBuffer[ MAXPATH-1 ] = '\0';
    }

	of.lpstrFile = fileNameBuffer;  // holds returned filename
	of.nMaxFile  = MAXPATH;




    //== Execute FileDialog >>=================================================

    Bool success = (flags & wxSAVE) ? GetSaveFileName(&of) : GetOpenFileName(&of);

    char* returnFileName = NULL;

    if ( success )
    {
        //=== Adding the correct extension >>=================================

        if ( defaultFilterIndex ) {
            *defaultFilterIndex = (int)of.nFilterIndex;
        }

	    if ( of.nFileExtension && fileNameBuffer[ of.nFileExtension-1] != '.' )
        {                                    // user has typed an filename
                                             // without an extension:

	        int   maxFilter = (int)(of.nFilterIndex*2L-1L);
	        extension       = filterBuffer;

	        for( int i = 0; i < maxFilter; i++ ) {		    // get extension
		        extension = extension + strlen( extension ) +1;
	        }

	        if (  (extension = strrchr( extension, '.' ))   // != "blabla" 
			      && !strrchr( extension, '*' )             // != "blabla.*"
			      && !strrchr( extension, '?' )             // != "blabla.?"
			      && extension[1]                           // != "blabla."
			      && extension[1] != ' ' )                  // != "blabla. "
	        {
                              // now concat extension to the fileName:

                int len = strlen( fileNameBuffer );
	            strncpy( fileNameBuffer + len, extension, MAXPATH - len );
                fileNameBuffer[ MAXPATH -1 ] = '\0';
            }
	    }

        returnFileName = fileNameBuffer;


	    //=== Simulating the wxOVERWRITE_PROMPT >>============================

	    if ( (flags & wxOVERWRITE_PROMPT) && ::FileExists( fileNameBuffer ) )
        {
		    char  questionText[] = "Replace file\n%s\n?";
		    char* messageText    = new char[strlen(questionText)+strlen(fileNameBuffer)-1];
		    sprintf( messageText, questionText, fileNameBuffer );

		    if ( messageText && ( wxMessageBox( messageText, title, wxYES_NO ) != wxYES ) )
            {
                returnFileName = NULL;
		    }

		    delete[] messageText;
	    }

    } // END: if ( success )


    delete[] filterBuffer;

    return returnFileName;
}
#endif
