// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I

#include <sm_w_mode.h>

#include <commdlg.h>
#include <owl\dc.h>
#include <owl\inputdia.h>
#include <owl\opensave.h>

windows_mode* wmode;

// a really 'orrible kludge is needed because of the fact the when the
// button notify procs are called, they aren't called with an object.
// There are other ways of handling this (e.g. static functions), but
// all in all the alternatives are even worse

#define RECURSE(function) \
  if (this != imode) \
  { imode->function(); \
    return; \
  } 

// define some useful colours
//const TColor BLACK(RGB(0, 0, 0)),
//				 WHITE(RGB(255, 255, 255));

// constuctor
midas_application::midas_application(LPSTR AName, windows_mode* wmodep) :
					 TApplication(AName)
{ strcpy(rev, "WMIDAS -- ");
  strcat(rev, AName);
  wm = wmodep;
}


// set up the main window
void midas_application::InitMainWindow(void)
{
// create a midas_window
  heap_check(mwp = new midas_window(wm, rev));

// make this the main window
  SetMainWindow(mwp);

  mwp->Attr.X = 0;
  mwp->Attr.Y = 0;
  mwp->Attr.W = 640 + 2 * frame_width();
  mwp->Attr.H = 80;
  mwp->Attr.Style = mwp->Attr.Style & ~WS_THICKFRAME;
  mwp->Attr.Style = mwp->Attr.Style & ~WS_MAXIMIZEBOX;

// create the buttons
  heap_check(bin_button = new primary_button((PTWindow)MainWindow, ID_BIN_BUTTON, "BIN", 50));
  heap_check(change_button = new primary_button((PTWindow)MainWindow, ID_CHANGE_BUTTON, "CHANGE", 70));
  heap_check(clipboard_button = new primary_button((PTWindow)MainWindow, ID_CLIPBOARD_BUTTON, "CLIPBOARD", 90));
  heap_check(comment_button = new primary_button((PTWindow)MainWindow, ID_COMMENT_BUTTON, "COMMENT", 80));
  heap_check(first_button = new primary_button((PTWindow)MainWindow, ID_FIRST_BUTTON, "FIRST", 50));
  heap_check(invert_button = new primary_button((PTWindow)MainWindow, ID_INVERT_BUTTON, "INVERT", 60));
  heap_check(last_button = new primary_button((PTWindow)MainWindow, ID_LAST_BUTTON, "LAST", 50));
  heap_check(next_button = new primary_button((PTWindow)MainWindow, ID_NEXT_BUTTON, "NEXT", 50));
  open_button = new primary_button((PTWindow)MainWindow, ID_OPEN_BUTTON, "OPEN", 50);
  plot_button = new primary_button((PTWindow)MainWindow, ID_PLOT_BUTTON, "PLOT", 50);
  plotall_button = new primary_button((PTWindow)MainWindow, ID_PLOTALL_BUTTON, "PLOTALL", 80);
  plotrmdr_button = new primary_button((PTWindow)MainWindow, ID_PLOTRMDR_BUTTON, "PLOTRMDR", 90);
  print_button = new primary_button((PTWindow)MainWindow, ID_PRINT_BUTTON, "PRINT", 50);
  printer_button = new primary_button((PTWindow)MainWindow, ID_PRINTER_BUTTON, "PRINTER", 70);
  prior_button = new primary_button((PTWindow)MainWindow, ID_PRIOR_BUTTON, "PRIOR", 50);
  replot_button = new primary_button((PTWindow)MainWindow, ID_REPLOT_BUTTON, "REPLOT", 60);
  set_button = new primary_button((PTWindow)MainWindow, ID_SET_BUTTON, "SET", 50);
  show_button = new primary_button((PTWindow)MainWindow, ID_SHOW_BUTTON, "SHOW", 50);
//  test_button = new primary_button((PTWindow)MainWindow, ID_TEST_BUTTON, "TEST", 50);

  busy_display = new TStatic((PTWindow)MainWindow, ID_BUSY_DISPLAY, "Static1",
				  0, 40, 320 + frame_width(), 20, 150);
  status_display = new TStatic((PTWindow)MainWindow, ID_BUSY_DISPLAY, "Static2",
				  320 + frame_width(), 40, 320 + frame_width(), 20, 100);
  busy_display->Attr.Style = busy_display->Attr.Style & ~WS_VISIBLE;
  busy_display->Attr.Style = busy_display->Attr.Style | SS_LEFTNOWORDWRAP;
  status_display->Attr.Style = status_display->Attr.Style & ~WS_VISIBLE;
  status_display->Attr.Style = status_display->Attr.Style | SS_CENTER;

// the basic canvas
  heap_check(cp = new popup(0, 0, 0, 640, 480, (PTWindow)MainWindow,
                           "[NO FILE]"));

// and the printer canvas; I choose 1350 x 975 pixels as a good
// compromise between resolution (2:1) and speed/memory needs. If
// you change these, you'll probably have to change the font size
// as well.
  const int printer_width = 1350, //2700,      // 9 x 6.5 on the page
            printer_height = 975; //1950;
  heap_check(winp = new popup(0, 0, 0, printer_width, printer_height,
                               (PTWindow)MainWindow, "NO TITLE", false));

  winp->Attr.W = printer_width;
  winp->Attr.H = printer_height;
  winp->init_bitmap();
  
  heap_check(logfont_pointer = new LOGFONT);;
// set everything to zero.
  byte* bp = (byte*)logfont_pointer;
  for (int n = 0; n < sizeof(LOGFONT); n++)
    bp[n] = 0;
  logfont_pointer->lfHeight = -20;
  winp->font(logfont_pointer);

  cp->Attr.X = 0;
  cp->Attr.Y = mwp->Attr.Y + mwp->Attr.H;

// The documentation is very hazy about the meaning of some of the system
// constants. I believe that the following is correct
  cp->Attr.W = 640 + 2 * frame_width();
  cp->Attr.H = 480 + title_height() + 2 * frame_height() - border_height();

  cp->Attr.Style |= (WS_THICKFRAME | WS_MAXIMIZEBOX | WS_CAPTION);
  mwp->cp(cp);

// make the canvas visible
  cp->show();

// create the invisible window
  invisible_window = new TWindow((PTWindow)MainWindow, "INVISIBLE");
  invisible_window->Attr.ExStyle |= WS_EX_TRANSPARENT;
  invisible_window->Attr.W = mwp->Attr.W - 2 * border_width();
  invisible_window->Attr.H = mwp->Attr.H - title_height();
  invisible_window->Attr.X = 0;
  invisible_window->Attr.Y = title_height();
  invisible_window->Attr.Style &= ~WS_VISIBLE;
  invisible_window->Attr.Style &= ~WS_CAPTION;
  invisible_window->Attr.Style &= ~WS_BORDER;
  invisible_window->Attr.Style |= WS_EX_TOPMOST;
  invisible_window->Attr.Style |= WS_POPUP;

// load the MIDAS icon
  LoadIcon("midas.ico");
}

// destructor. This is just to be neat and tidy
midas_application::~midas_application(void)
{ delete cp;
  delete winp;
  delete logfont_pointer;
}

// constructor
midas_window::midas_window(windows_mode* wmp, LPSTR ATitle)
		  : TFrameWindow(0, ATitle)
{ wm = wmp;
//  this_instance = hInstance; 2.0
  menu_handler = NULL;
  green_brush = CreateSolidBrush(RGB(0, 127, 0));
  red_brush = CreateSolidBrush(RGB(255, 0, 0));
}

void midas_window::GetWindowClass(WNDCLASS& AWndClass)
{ TWindow::GetWindowClass(AWndClass);
// the following causes a GP fault after several instantiations
//  AWndClass.hIcon = LoadIcon(this_instance, "midas_icon");
};

// handle the primary buttons
void midas_window::handle_bin_button(UINT)
{ wm->_bin();
}

void midas_window::handle_change_button(UINT)
{ switch (wm->Tplotmode)
  { case UNBINNED_SPECTRUM:
	 case BINNED_SPECTRUM:
	 { edit_control edc(wm->app->change_button, "CHANGE", 3);
		edc.label(1, "MIN CHANNEL:")
			.value(1, wm->Start_channel)
			.label(2, "MAX CHANNEL:")
			.value(2, wm->End_channel)
			.label(3, "DURATION (MINS):")
			.value(3, wm->Duration)
			.execute();
		wm->Start_channel = atoi(edc.value(1));
		wm->End_channel = atoi(edc.value(2));
		wm->Duration = atoi(edc.value(3));
		break;
	 }
	 case UNBINNED_TOMPLOT:
	 case BINNED_TOMPLOT:
	 { edit_control edc(wm->app->change_button, "CHANGE", 3);
		edc.label(1, "MIN CHANNEL:")
			.value(1, wm->Start_tomplot_channel)
			.label(2, "N CHANNELS:")
			.value(2, wm->N_tomplot_channels)
			.label(3, "DURATION (MINS):")
			.value(3, wm->Duration)
			.execute();
		if ((atoi(edc.value(1)) + atoi(edc.value(2)) - 1) > 200) then
		  warning("Invalid lowest frequency channel");
		wm->Start_tomplot_channel = atoi(edc.value(1));
		wm->N_tomplot_channels = atoi(edc.value(2));
		wm->Duration = atoi(edc.value(3));
		break;
	 }
	 case GS2_HIGH_RES:
	 { edit_control edc(wm->app->change_button, "CHANGE", 3);
		edc.label(1, "CHANNEL:")
			.value(1, wm->High_res_channel)
			.label(2, "N DATA POINTS:")
			.value(2, wm->Gs2_n_data)
			.label(3, "N STRIPS:")
			.value(3, wm->Gs2_n_strips)
			.execute();
		wm->High_res_channel = atoi(edc.value(1));
		wm->Gs2_n_data = atoi(edc.value(2));
		wm->Gs2_n_strips = atoi(edc.value(3));
		break;
	 }
  }
}

void midas_window::handle_clipboard_button(UINT)
{ cwp->copy_to_clipboard();
}

// set the comment string
void midas_window::handle_comment_button(UINT)
{ edit_control edc(wm->app->comment_button, "COMMENT", 1);
  edc.label(1, "COMMENT:")
	  .value(1, wm->Comment)
	  .execute();
  wm->Comment = edc.value(1);
}

void midas_window::handle_first_button(UINT)
{ wm->first(); }

void midas_window::handle_invert_button(UINT)
{ wm->Pad->invert(); }

void midas_window::handle_last_button(UINT)
{ wm->last(); }

void midas_window::handle_next_button(UINT)
{ wm->next(); }

void midas_window::handle_open_button(UINT)
{ // get a filename, then open it
  DWORD filedata_flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST |
								 OFN_PATHMUSTEXIST |OFN_NOCHANGEDIR ;
  TOpenSaveDialog::TData filedata(filedata_flags,
									"Data files (*.dat) | *.dat");
  if ((TFileOpenDialog((TWindow*)this, filedata).Execute()) == IDOK)
  { wm->app->invisible_window->Show(SW_SHOWNORMAL);
	 wm->_open((DREstring)filedata.FileName);

// change the title bar of the canvas window
//	 DREstring canvas_caption = (DREstring)"[" + wm->Current_file_name + "]";
//	 cwp->SetWindowText(canvas_caption);
	 wm->_retitle_canvas();
	 cwp->clear();
	 wm->app->invisible_window->Show(SW_HIDE);
  }
}

void midas_window::handle_plot_button(UINT)
{ switch (wm->Tplotmode)
  { case GS2_LOW_RES :
    { if (wm->Gs2_frame_pds || wm->Gs2_frame_jpl) then
        wm->_plot_full_frame();
      break;
    }
    case GS2_HIGH_RES :
    { if (wm->Gs2_frame_pds || wm->Gs2_frame_jpl) then
      { edit_control edc(wm->app->plot_button, "HI RES", 2);
        edc.label(1, "LINE:")
           .value(1, wm->Current_phiex_position.line())
           .label(2, "DATUM:")
           .value(2, wm->Current_phiex_position.datum())
           .execute();
        wm->Current_phiex_position = phiex_position(atoi(edc.value(1)),
                                                    atoi(edc.value(2)));
        wm->_plot_gs2_hi_res(wm->Current_phiex_position,
                             wm->Gs2_n_data, wm->Gs2_n_strips);
      }
      break;
    }
    default :
    { if (wm->Edr_f) then
      { edit_control edc(wm->app->plot_button, "PLOT", 4);
        edc.label(1, "YEAR:")
           .value(1, wm->Start_time.year())
           .label(2, "DAY:")
           .value(2, wm->Start_time.day() + 1)
           .label(3, "HOUR:")
           .value(3, wm->Start_time.hour())
           .label(4, "MINUTE:")
           .value(4, wm->Start_time.minute())
           .execute();
        wm->Start_time.year(atoi(edc.value(1)));
        wm->Start_time.day(atoi(edc.value(2)) - 1);
        wm->Start_time.hour(atoi(edc.value(3)));
        wm->Start_time.minute(atoi(edc.value(4)));
        wm->Start_time.second(0);

        wm->_execute_low_rate_plot_command();
      }
      break;
    }
  }
}

void midas_window::handle_plotall_button(UINT)
{ wm->plotall(); }

void midas_window::handle_plotrmdr_button(UINT)
{ wm->plotrmdr(); }

void midas_window::handle_print_button(UINT)
{ wm->print(); }

void midas_window::handle_printer_button(UINT)
{ PRINTDLG pd;
  memset(&pd, 0, sizeof(PRINTDLG));
  pd.lStructSize = sizeof(PRINTDLG);
  pd.hwndOwner = wm->app->printer_button->HWindow;
// explicitly set some NULLs
  pd.hDevMode = 0;
  pd.hDevNames = 0;

  const int status = PrintDlg(&pd);
  if (status) then
  { DEVNAMES * nam = (DEVNAMES*)GlobalLock(pd.hDevNames);
//    DEVMODE * devmod = (DEVMODE*)GlobalLock(pd.hDevMode);

// change the values in the windows31 surface
	 int offset = nam->wDriverOffset;
    char* cp = (char*)nam;
    cp += offset;
    wm->w31p->print_driver(cp);

    offset = nam->wDeviceOffset;
    cp = (char*)nam;
    cp += offset;
    wm->w31p->print_device(cp);

	 offset = nam->wOutputOffset;
    cp = (char*)nam;
    cp += offset;
    wm->w31p->print_port(cp);

	 GlobalUnlock(pd.hDevNames);
	 GlobalUnlock(pd.hDevMode);
	 GlobalFree(pd.hDevNames);
	 GlobalFree(pd.hDevMode);
  }
}

void midas_window::handle_prior_button(UINT)
{ wm->prior(); }

void midas_window::handle_replot_button(UINT)
{ wm->replot(); }

void midas_window::handle_set_button(UINT)
{ switch (pmd(wm->app->set_button, "SET").item("PLOTMODE")
													  .item("DISPLAY")
													  .item("SCMODE")
													  .item("PRAMODE")
													  .item("FILE TYPE")
													  .execute())
  { case 0 : wm->_set_plot_mode();
				 break;
    case 1 : wm->_set_display();
             break;
	 case 2 : wm->_set_sc_mode();
				 break;
	 case 3 : wm->_set_pra_mode();
				 break;
	 case 4 : wm->_set_file_type();
				 break;
	 default : wm->error("Invalid menu selection");
				  break;
  }
}

void midas_window::handle_show_button(UINT)
{ switch (pmd(wm->app->show_button, "SHOW").item("PRA MODES")
														 .item("SC MODES")
														 .item("TIME RANGE")
														 .execute())
  { case 0 : wm->_show_pra_modes();
				 break;
	 case 1 : wm->_show_sc_modes();
				 break;
	 case 2 : wm->_show_time_range();
				 break;
	 default : wm->error("Invalid menu selection");
				  break;
  }
}

void midas_window::handle_test_button(UINT)
{ /* wm->test(); 2.0 */ }

// handle the secondary buttons
void midas_window::handle_image_button(UINT)
{ edit_control edc(wm->app->image_button, "IMAGE", 2);
  edc.label(1, "BRIGHTNESS:")
	  .value(1, DREstring10(wm->Brightness))
     .label(2, "SATURATION:")
	  .value(2, DREstring10(wm->Saturation))
	  .execute();
  wm->Brightness = atol(edc.value(1));
  wm->Saturation = atol(edc.value(2));
}

void midas_window::handle_range_button(UINT)
{ edit_control edc(wm->app->range_button, "RANGE", 3);
  edc.label(1, "CHANNEL:")
	  .value(1, "0")
	  .label(2, "LOW VALUE:")
	  .value(2, "0")
	  .label(3, "HIGH VALUE:")
	  .value(3, "255")
	  .execute();
  const int16 channel_nr = (int16)atol(edc.value(1));
  const uint16 low_val = (uint16)atol(edc.value(2)),
					high_val = (uint16)atol(edc.value(3));
  wm->Autoscale_tomplot = (channel_nr == -1);
  if (!wm->Autoscale_tomplot) then
  { if (channel_nr) then
	 { wm->Tomplot_dn_range[channel_nr][0] = low_val;
		 wm->Tomplot_dn_range[channel_nr][1] = high_val;
	 }
	 else
	 { for (int n = 3; n <= 200; n++)
		{ wm->Tomplot_dn_range[n][0] = low_val;
		  wm->Tomplot_dn_range[n][1] = high_val;
		}
	 }
  }
}


void midas_window::handle_menu(UINT)
{ const int index = _lbp->GetSelIndex();
  _lbp->hide();
  (this->*menu_handler)(index);
}

// handle WM_CTLCOLOR messages posted to the statics
HBRUSH midas_window::EvCtlColor(HDC hdc, HWND hwnd, UINT)
{ if (hwnd == wm->app->busy_display->HWindow) then       // busy
  { SetTextColor(hdc, RGB(255, 255, 255));
	 SetBkColor(hdc, RGB(255, 0, 0));
	 return red_brush;
  }
  if (hwnd == wm->app->status_display->HWindow) then     // status
  { SetTextColor(hdc, RGB(0, 0, 0));
	 SetBkColor(hdc, RGB(0, 127, 0));
	 return green_brush;
  }
}

// constructor
windows_mode::windows_mode(const double rev_nr)
{ app = new midas_application((LPSTR)(const char*)(DREstring(rev_nr, 3.2)),
					this);
  app->InitApplication();
  app->InitInstance();

  w31p = new windows31(app->cp, false);   // a visible surface
  win_printer_pointer = new windows_printer(app->winp, false); // a printer surface
  Screen_device = w31p;
  Hardcopy_device = win_printer_pointer;
  Pad = Screen_device;

  _create_image_control();

// Initialise an array to hold the names of the plot modes
  _plot_mode_name[UNBINNED_SPECTRUM] = "UNBINNED SPECTRUM";
  _plot_mode_name[BINNED_SPECTRUM] = "BINNED SPECTRUM";
  _plot_mode_name[RAWPLOT] = "RAW DN";
  _plot_mode_name[UNBINNED_TOMPLOT] = "UNBINNED TOMPLOT";
  _plot_mode_name[BINNED_TOMPLOT] = "BINNED TOMPLOT";
  _plot_mode_name[GS2_LOW_RES] = "GS2 LOW RES";
  _plot_mode_name[GS2_HIGH_RES] = "GS2 HIGH RES";
}

// destructor
windows_mode::~windows_mode(void)
{ destroy(w31p);
  destroy(app); 
}

// private functions

// create the image control
void windows_mode::_create_image_control(void)
{ if (image < secondary_controls_present) then
    return;

// create the control
  app->image_button = new secondary_button((PTWindow)(app->MainWindow),
			ID_IMAGE_BUTTON, "IMAGE", 50);
  secondary_controls_present += image;
}

// create the range control
void windows_mode::_create_range_control(void)
{ if (range < secondary_controls_present) then
	 return;

// create the control
  app->range_button = new secondary_button((PTWindow)(app->MainWindow),
			ID_RANGE_BUTTON, "RANGE", 50);
  secondary_controls_present += range;
}

void windows_mode::delete_secondary_controls(void)
{ for (int n = 0; n < N_SECONDARY_CONTROLS; n++)
	 delete_secondary_control(n);
}

// delete a secondary control -- just a switch
void windows_mode::delete_secondary_control(const int control)
{ if (!(control < secondary_controls_present)) then
    return;

  switch (control)
  { case image : destroy(app->image_button);
                 break;
    case range : destroy(app->range_button);
                 break;
  }

  secondary_controls_present -= image;
}

void windows_mode::_clear_text_panel(void)
{ /* for (int n = 0; n < N_TEXT_PANEL_ITEMS; n++)
    text_panel_item[n]->clear();
  text_panel->caret_item(1);  */
}                              

void windows_mode::_display_in_window(const char* label,
												  DREstring& msg/*, const colour fgc,
                                      const colour bgc */)
{ MessageBox(app->mwp->HWindow, msg, label, MB_OK);

}

void windows_mode::_pol_contrast(void)
{  }

void windows_mode::_pol_threshold(void)
{  }

void windows_mode::_set_plot_mode(void)
{ switch (Tplotmode = pmd(app->set_button, "SET PLOTMODE")
								  .item("Unbinned spectral scans")
								  .item("Binned spectral scans")
								  .item("Raw DN scans")
								  .item("Unbinned Tomplots")
								  .item("Binned Tomplots")
								  //.item("LHC spectral scans (48 sec)")
								  //.item("RHC spectral scans (48 sec)")
								  //.item("Polarised spectral scans (48 sec)")
								  //.item("VIM plots")
								  .item("Low resolution GS-2")
								  .item("High resolution GS-2")
								  .selected(Tplotmode)
								  .execute())
  {  case UNBINNED_SPECTRUM :
	 case BINNED_SPECTRUM :
	 { _plot_function = &operating_mode::display_spectral;
		delete_secondary_controls();
		_create_image_control();
		break;
	 }
	 case RAWPLOT:
	 { _plot_function = &operating_mode::_rawplot;
		delete_secondary_controls();
		break;
	 }
	 case UNBINNED_TOMPLOT:
	 case BINNED_TOMPLOT :
	 { _plot_function = &operating_mode::_tomplot;
		delete_secondary_controls();
		_create_range_control();
		break;
	 }
	 case GS2_LOW_RES :
	 case GS2_HIGH_RES :
	 { delete_secondary_controls();
		break;
	 }

	 default : error("Invalid menu selection");
			break;
  }
  _retitle_canvas();
}

void windows_mode::_retitle_canvas(void)
{// change the title bar of the caption window
	 DREstring canvas_caption = (DREstring)"[" + Current_file_name + "]";
	 canvas_caption += (DREstring)" -- " + _plot_mode_name[Tplotmode];
	 app->mwp->cwp->SetWindowText(canvas_caption);
}

void windows_mode::_set_display(void)
{ switch (pmd(app->set_button, "SET DISPLAY").item("SCREEN")
                                             .item("PRINTER")
                                            // .selected((int)File_type)
                                             .execute())
  { case 0 : Pad = Screen_device;
             To_file = false;
             break;
    case 1 : Pad = Hardcopy_device;
             To_file = false;
             break;
//    case 3 : Pad = Hardcopy_device; To_file = true; break;
  }
}

void windows_mode::_set_file_type(void)
{ switch (pmd(app->set_button, "SET FILE TYPE").item("FIXED")
                                               .item("VARIABLE")
                                               .item("JPL PHIEX")
				                                   .item("PDS PHIEX")
                                               .item("PDS BROWSE")
                                               .item("PDS BBROWSE")
				                                   .item("PDS")
                                               .selected((int)File_type)
                                               .execute())
  { case fixed :
      File_type = fixed;
      break;
	 case variable :
      File_type = variable;
      break;
	 case jpl_phiex :
      File_type = jpl_phiex;
      break;
	 case pds_phiex :
      File_type = pds_phiex;
      break;
	 case pds_browse :
      File_type = pds_browse;
//      Current_sc_mode = browse;
      break;
	 case pds_bbrowse :
      File_type = pds_bbrowse;
//      Current_sc_mode = browse;
      break;
	 case pds :
      File_type = pds;
      break;
  }
}

// set the pra mode for subsequent plots
void windows_mode::_set_pra_mode(void)
{ pmd selection_list(app->set_button, "SET PRA MODE");

  for (int i = 0; i <= 6; i++)
	 selection_list.item(_pra_mode_name[i]);

  selection_list.selected(Current_pra_mode);
  Current_pra_mode = selection_list.execute();
}

// set the spacecraft mode for subsequent plots
void windows_mode::_set_sc_mode(void)
{ pmd selection_list(app->set_button, "SET SC MODE");

  for (int i = 0; i <= 31; i++)
	 selection_list.item(_sc_mode_name[i]);

  selection_list.selected(Current_sc_mode);
  Current_sc_mode = selection_list.execute();
}

/*void windows_mode::_show_range(void)
{ if (!Edr_f) then
	 error("No file open");
  else
	 _display_in_window("TIME RANGE", _time_range_string(), black, white);
} */

/* void windows_mode::_show_sc_modes(void)
{ _display_in_window("SC-MODES", _sc_modes_string(), black, white); } */

/*int windows_mode::_temp_slider(string& label,
											  const int current_value,
											  const int min_display,
											  const int max_display)
{ const int EXTRA_SLIDER_WIDTH = 350;

  frame slider_frame(base_frame);
  slider_frame.no_confirm(TRUE).inherit_colours(TRUE).below(*sub_button_panel);
  panel slider_panel(slider_frame);
  slider_panel.consume_pick_event(WIN_MOUSE_BUTTONS);
  slider s(slider_panel);
  s.min_value(min_display).max_value(max_display).width(255)
   .value(current_value).notify_level(PANEL_DONE)
   .notify_proc(&window_return).label_string(label);
  slider_panel.fit_height();
  slider_frame.fit_height();
  slider_frame.width(max_display - min_display + EXTRA_SLIDER_WIDTH);
  slider_panel.paint();
// for some reason, changing colours renders the bar invisible
//  colourmap frame_cmap(slider_frame, "slider_cmap", 2);
//  colourmap slider_cmap(slider_panel, "slider_cmap", 2);
//  set_colour(slider_cmap, 0, colour(150, 100, 0));
//  set_colour(slider_cmap, 1, colour(150, 255, 100));
//  slider_panel.paint();
//  s.paint();
  window_loop((Frame)slider_frame);
  return s.value();
}    */

/*void windows_mode::_text_item_position(const int p0, const int p1,
                                           const int p2, const int p3)
{ if (p0 != -1) then
    text_panel_item[0]->label_x(p0);
  if (p1 != -1) then
    text_panel_item[1]->label_x(p1);
  if (p2 != -1) then
    text_panel_item[2]->label_x(p2);
  if (p3 != -1) then
    text_panel_item[3]->label_x(p3);
}  */

/*void windows_mode::_tomplot_range(void)
{ RECURSE(_tomplot_range)
  _text_item_position(0, 200, 400);
  text_panel_item[0]->label("Channel_number : ").notify_proc(&_tomplot_range_1);
  text_panel_item[1]->label("Low value : ").notify_proc(&_tomplot_range_1);
  text_panel_item[2]->label("High value : ").notify_proc(&_tomplot_range_1);
  text_panel->caret_item(1);
}  */

/*void windows_mode::_tomplot_range_1(void)
{ RECURSE(_tomplot_range_1)
  int channel_nr, temp_int, n;

  if (!(text_panel->caret_on_item(3))) then
    text_panel->advance_caret();
  else
  { sscanf(text_panel_item[0]->value(), "%d", &channel_nr);
	 sscanf(text_panel_item[1]->value(), "%d", &temp_int);
    if (channel_nr) then
      Tomplot_dn_range[channel_nr][0] = (byte)temp_int;
    else
      for (n = 3; n <= 200; n++)
        Tomplot_dn_range[n][0] = (byte)temp_int;
    sscanf(text_panel_item[2]->value(), "%d", &temp_int); 
    if (channel_nr) then
      Tomplot_dn_range[channel_nr][1] = (byte)temp_int;
    else
      for (n = 3; n <= 200; n++)
        Tomplot_dn_range[n][1] = (byte)temp_int;
    _clear_text_panel();
  }
}*/

// commands

/*void windows_mode::calibrate(void)
{ RECURSE(calibrate)
  Calibrate = 1 - Calibrate;
  if (Calibrate) then
    (*calibrate_button).label_image(panel_button_image(calibrate_button->parent(), "NOCALIBRATE", 12, 0));
  else
    (*calibrate_button).label_image(panel_button_image(calibrate_button->parent(), "CALIBRATE", 12, 0));
  button_panel->paint();
} */

/*void windows_mode::comment(void)
{ RECURSE(comment)
  if (!*(text_panel_item[0]->label())) then
    text_panel_item[0]->label(" Comment : ").notify_proc(&comment);
   else
   { Comment = text_panel_item[0]->value();
     _clear_text_panel();
   }
}*/

/*void windows_mode::dump(void)
{ RECURSE(dump)
  if (!*(text_panel_item[0]->label())) then
    text_panel_item[0]->label("Dump file name : ").notify_proc(&dump);
  else
  { Pad->dump(text_panel_item[0]->value());
    _clear_text_panel();
  }
}*/

/*void windows_mode::ignore(void)
{ RECURSE(ignore)
  Low_ignore_value = _temp_slider("Low ignore value : ",
                                  Low_ignore_value, 0, 255);
  High_ignore_value = _temp_slider("High ignore_value : ",
                                   High_ignore_value, 0, 255);
  for (int n = Low_ignore_value; n <= High_ignore_value; n++) 
    Valid_data[n] = false;
} */

/*void windows_mode::plot(void)
{ RECURSE(plot)
  switch (Tplotmode)
  { case GS2_LOW_RES : _plot_full_frame(); break;
    case GS2_HIGH_RES : 
    { text_panel_item[0]->label("Line : ").notify_proc(&_plot_2);
      text_panel_item[1]->label("Datum : ").notify_proc(&_plot_2);
      text_panel->caret_item(1);
		break;
    }
  };
  if (Tplotmode < GS2_LOW_RES) then
  { _text_item_position(0, 150, 300, 450);
    text_panel_item[0]->label("Year : ").notify_proc(&_plot_1);
    text_panel_item[1]->label("Day : ").notify_proc(&_plot_1);
    text_panel_item[2]->label("Hour : ").notify_proc(&_plot_1);
    text_panel_item[3]->label("Minute : ").notify_proc(&_plot_1);
    text_panel->caret_item(1);
  }
}*/

// To print we print the constituent surface
void windows_mode::print(void)
{ w31p->print(); }

/*void windows_mode::printer(void)
{ RECURSE(printer)
  if (!*(text_panel_item[0]->label())) then
    text_panel_item[0]->label("Printer name : ").notify_proc(&windows_mode::printer);
  else
  { Printer_name = text_panel_item[0]->value();
	 _clear_text_panel();
  }
} */

/*void windows_mode::recall(void)
{ RECURSE(recall)
  Low_recall_value = _temp_slider("Low recall value : ", Low_recall_value, 0, 255);
  High_recall_value = _temp_slider("High recall_value : ", High_recall_value, 0,
                             255);
  for (int n = Low_recall_value; n <= High_recall_value; n++) 
    Valid_data[n] = true;
} */

// non-command functions
void windows_mode::display_status(DREstring& msg)
{ yield();
  if (!(int)msg) then
  { app->status_display->Show(SW_HIDE);
	 return;
  }

  app->status_display->Show(SW_SHOWNORMAL);
  TWindowDC status_hdc(app->status_display->HWindow);
  status_hdc.SetBkColor(RGB(0, 0, 255));
  status_hdc.SetTextColor(RGB(255, 255, 0));
  status_hdc.SelectStockObject(ANSI_VAR_FONT); // doesn't do anything
//  busy_hdc.TextOut(0, 0, t, -1);
  app->status_display->SetText(msg);}

void windows_mode::error(DREstring& message)
{ MessageBeep(MB_ICONQUESTION);
  _display_in_window("ERROR", message);
}

void windows_mode::busy(DREstring& msg)
{ yield();

  DREstring t = "MIDAS is busy...";

  if ((int)msg) then
	t += ((DREstring)"(" + msg + (DREstring)")");

  app->invisible_window->Show(SW_SHOWNORMAL);
  app->busy_display->Show(SW_SHOWNORMAL);
  TWindowDC busy_hdc(app->busy_display->HWindow);
  busy_hdc.SetBkColor(RGB(0, 0, 255));
  busy_hdc.SetTextColor(RGB(255, 255, 0));
//  busy_hdc.SelectStockObject(SYSTEM_FONT);  // doesn't do anything
//  busy_hdc.TextOut(0, 0, t, -1);
  app->busy_display->SetText(t);
}

void windows_mode::unbusy(void)
{ app->busy_display->Show(SW_HIDE);
  app->invisible_window->Show(SW_HIDE);
}

void windows_mode::test(void)
{
}

// Define the response table for the buttons
DEFINE_RESPONSE_TABLE1(midas_window, TFrameWindow)
EV_WM_CTLCOLOR,
EV_CHILD_NOTIFY_ALL_CODES(ID_BIN_BUTTON, handle_bin_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_CHANGE_BUTTON, handle_change_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_CLIPBOARD_BUTTON, handle_clipboard_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_COMMENT_BUTTON, handle_comment_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_FIRST_BUTTON, handle_first_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_IMAGE_BUTTON, handle_image_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_INVERT_BUTTON, handle_invert_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_LAST_BUTTON, handle_last_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_NEXT_BUTTON, handle_next_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_OPEN_BUTTON, handle_open_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_PLOT_BUTTON, handle_plot_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_PLOTALL_BUTTON, handle_plotall_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_PLOTRMDR_BUTTON, handle_plotrmdr_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_PRINT_BUTTON, handle_print_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_PRINTER_BUTTON, handle_printer_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_PRIOR_BUTTON, handle_prior_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_RANGE_BUTTON, handle_range_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_REPLOT_BUTTON, handle_replot_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_SET_BUTTON, handle_set_button),
EV_CHILD_NOTIFY_ALL_CODES(ID_SHOW_BUTTON, handle_show_button),
END_RESPONSE_TABLE;

