// generated by Fast Light User Interface Designer (fluid) version 1.0300

#include "/home/ddong/COSM_Source_Base/build/psf/gui/psfGUI.h"
#include "psfAbout.h"
#include "FL/Fl_Native_File_Chooser.H"
#include "psfMain.h"
#include "wu/wuHeader.h"
#include "tinyxml/tinyxml.h"
#include <blitz/timer.h>
#include <FL/Fl_Sys_Menu_Bar.H>
#include <FL/fl_ask.H>
#include <stdlib.h>
#include <map>

void PsfGUI::cb_Quit_i(Fl_Menu_*, void*) {
  exit(0);
}
void PsfGUI::cb_Quit(Fl_Menu_* o, void* v) {
  ((PsfGUI*)(o->parent()->user_data()))->cb_Quit_i(o,v);
}

void PsfGUI::cb_About_i(Fl_Menu_*, void*) {
  if (!aboutDialog) {
    make_about();
}
aboutDialog->show();
}
void PsfGUI::cb_About(Fl_Menu_* o, void* v) {
  ((PsfGUI*)(o->parent()->user_data()))->cb_About_i(o,v);
}

Fl_Menu_Item PsfGUI::menu_[] = {
 {"File", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 12, 0},
 {"Quit", 0,  (Fl_Callback*)PsfGUI::cb_Quit, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {0,0,0,0,0,0,0,0,0},
 {"Help", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 12, 0},
 {"About...", 0,  (Fl_Callback*)PsfGUI::cb_About, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {0,0,0,0,0,0,0,0,0},
 {0,0,0,0,0,0,0,0,0}
};

void PsfGUI::cb_Browse_i(Fl_Button*, void*) {
  Fl_Native_File_Chooser native;

native.title("Select Filename to Write");
native.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE);
native.filter("*.wu");
native.show();
filenameInput->value(native.filename());
}
void PsfGUI::cb_Browse(Fl_Button* o, void* v) {
  ((PsfGUI*)(o->parent()->user_data()))->cb_Browse_i(o,v);
}

void PsfGUI::cb_Generate_i(Fl_Button*, void*) {
  psfProgress->value(0);
switch( psfPrecisionInput->value() ) {
    case 0: generatePsf<float>(); break;
    case 1: generatePsf<double>(); break;
    case 2: generatePsf<long double>(); break;
};
}
void PsfGUI::cb_Generate(Fl_Button* o, void* v) {
  ((PsfGUI*)(o->parent()->user_data()))->cb_Generate_i(o,v);
}

void PsfGUI::cb_interpolateCheck_i(Fl_Round_Button*, void*) {
  if ( interpolateCheck->value() )
{
    exactCheck->value(false);
}
else
{
    exactCheck->value(true);
};
}
void PsfGUI::cb_interpolateCheck(Fl_Round_Button* o, void* v) {
  ((PsfGUI*)(o->parent()->parent()->user_data()))->cb_interpolateCheck_i(o,v);
}

void PsfGUI::cb_exactCheck_i(Fl_Round_Button*, void*) {
  if ( exactCheck->value() )
{
    interpolateCheck->value(false);
}
else
{
    interpolateCheck->value(true);
};
}
void PsfGUI::cb_exactCheck(Fl_Round_Button* o, void* v) {
  ((PsfGUI*)(o->parent()->parent()->user_data()))->cb_exactCheck_i(o,v);
}

Fl_Menu_Item PsfGUI::menu_psfModelInput[] = {
 {"Gibson_Lanni1992", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {"Haeberle", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {"Mod_Gibson_Lann", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {0,0,0,0,0,0,0,0,0}
};

void PsfGUI::cb_Non_i(Fl_Menu_*, void*) {
  confocalTab->deactivate();
dicTab->deactivate();
exactCheck->activate();
}
void PsfGUI::cb_Non(Fl_Menu_* o, void* v) {
  ((PsfGUI*)(o->parent()->parent()->user_data()))->cb_Non_i(o,v);
}

void PsfGUI::cb_2_i(Fl_Menu_*, void*) {
  confocalTab->deactivate();
dicTab->deactivate();
exactCheck->activate();
}
void PsfGUI::cb_2(Fl_Menu_* o, void* v) {
  ((PsfGUI*)(o->parent()->parent()->user_data()))->cb_2_i(o,v);
}

void PsfGUI::cb_Confocal_i(Fl_Menu_*, void*) {
  interpolateCheck->value(true);
exactCheck->value(false);
confocalTab->activate();
dicTab->deactivate();
exactCheck->deactivate();
}
void PsfGUI::cb_Confocal(Fl_Menu_* o, void* v) {
  ((PsfGUI*)(o->parent()->parent()->user_data()))->cb_Confocal_i(o,v);
}

void PsfGUI::cb_Confocal1_i(Fl_Menu_*, void*) {
  interpolateCheck->value(true);
exactCheck->value(false);
confocalTab->activate();
dicTab->deactivate();
exactCheck->deactivate();
}
void PsfGUI::cb_Confocal1(Fl_Menu_* o, void* v) {
  ((PsfGUI*)(o->parent()->parent()->user_data()))->cb_Confocal1_i(o,v);
}

void PsfGUI::cb_DIC_i(Fl_Menu_*, void*) {
  interpolateCheck->value(true);
exactCheck->value(false);
dicTab->activate();
confocalTab->deactivate();
exactCheck->deactivate();
}
void PsfGUI::cb_DIC(Fl_Menu_* o, void* v) {
  ((PsfGUI*)(o->parent()->parent()->user_data()))->cb_DIC_i(o,v);
}

Fl_Menu_Item PsfGUI::menu_psfTypeInput[] = {
 {"Non-Confocal", 0,  (Fl_Callback*)PsfGUI::cb_Non, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {"2-Photon", 0,  (Fl_Callback*)PsfGUI::cb_2, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {"Confocal-Circular", 0,  (Fl_Callback*)PsfGUI::cb_Confocal, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {"Confocal-Line", 0,  (Fl_Callback*)PsfGUI::cb_Confocal1, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {"DIC", 0,  (Fl_Callback*)PsfGUI::cb_DIC, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0}
};

Fl_Menu_Item PsfGUI::menu_psfPrecisionInput[] = {
 {"Single (32 bit)", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {"Double (64bit)", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {"Long Double (80 bit)", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 12, 0},
 {0,0,0,0,0,0,0,0,0}
};

void PsfGUI::cb_Browse1_i(Fl_Button*, void*) {
  Fl_Native_File_Chooser native;

native.title("Select Filename to Read");
native.type(Fl_Native_File_Chooser::BROWSE_FILE);
native.filter("*.xml");
native.show();
xmlInput->value(native.filename());
}
void PsfGUI::cb_Browse1(Fl_Button* o, void* v) {
  ((PsfGUI*)(o->parent()->user_data()))->cb_Browse1_i(o,v);
}

void PsfGUI::cb_Open_i(Fl_Button*, void*) {
  if ( xmlInput != NULL && xmlInput->value() ) {
    readParameters();
}
else
{
    fl_alert("PSF XML Input Configuration Filename not Specified");
};
}
void PsfGUI::cb_Open(Fl_Button* o, void* v) {
  ((PsfGUI*)(o->parent()->user_data()))->cb_Open_i(o,v);
}

PsfGUI::PsfGUI() {
  { psfWindow = new Fl_Double_Window(974, 649, "COSM Psf");
    psfWindow->user_data((void*)(this));
    { Fl_Sys_Menu_Bar* o = new Fl_Sys_Menu_Bar(0, 0, 1000, 25);
      o->box(FL_UP_BOX);
      o->color(FL_BACKGROUND_COLOR);
      o->selection_color(FL_SELECTION_COLOR);
      o->labeltype(FL_NORMAL_LABEL);
      o->labelfont(0);
      o->labelsize(14);
      o->labelcolor(FL_FOREGROUND_COLOR);
      o->align(Fl_Align(FL_ALIGN_CENTER));
      o->when(FL_WHEN_RELEASE_ALWAYS);
      Fl_Group::current()->resizable(o);
      o->menu(menu_);
    } // Fl_Sys_Menu_Bar* o
    { filenameInput = new Fl_File_Input(375, 540, 440, 30, "PSF Filename:");
      filenameInput->tooltip("Path and filename of PSF to be generated");
      filenameInput->labelsize(12);
      filenameInput->textsize(12);
    } // Fl_File_Input* filenameInput
    { Fl_Button* o = new Fl_Button(845, 545, 90, 25, "Browse...");
      o->labelsize(12);
      o->callback((Fl_Callback*)cb_Browse);
    } // Fl_Button* o
    { psfProgress = new Fl_Progress(40, 610, 895, 20, "Progress");
      psfProgress->tooltip("Progress of PSF image generation");
      psfProgress->selection_color((Fl_Color)230);
      psfProgress->labelsize(12);
    } // Fl_Progress* psfProgress
    { Fl_Button* o = new Fl_Button(845, 575, 90, 25, "Generate");
      o->tooltip("Generate PSF image file");
      o->labelsize(12);
      o->callback((Fl_Callback*)cb_Generate);
    } // Fl_Button* o
    { Fl_Group* o = new Fl_Group(40, 130, 895, 380);
      o->box(FL_ENGRAVED_BOX);
      { interpolateCheck = new Fl_Round_Button(140, 170, 155, 25, "Radial Interpolation");
        interpolateCheck->tooltip("Compute  PSF using radial interpolation");
        interpolateCheck->down_box(FL_ROUND_DOWN_BOX);
        interpolateCheck->labelsize(12);
        interpolateCheck->callback((Fl_Callback*)cb_interpolateCheck);
      } // Fl_Round_Button* interpolateCheck
      { exactCheck = new Fl_Round_Button(140, 190, 150, 25, "Exact Evaluation");
        exactCheck->tooltip("Compute PSF using exact value");
        exactCheck->down_box(FL_ROUND_DOWN_BOX);
        exactCheck->value(1);
        exactCheck->labelsize(12);
        exactCheck->callback((Fl_Callback*)cb_exactCheck);
      } // Fl_Round_Button* exactCheck
      { psfErrorInput = new Fl_Value_Input(230, 360, 75, 20, "Absolute Error :");
        psfErrorInput->labelsize(12);
        psfErrorInput->value(1e-06);
        psfErrorInput->textsize(12);
      } // Fl_Value_Input* psfErrorInput
      { psfLMInput = new Fl_Value_Input(230, 380, 75, 20, "Lateral Magnification:");
        psfLMInput->labelsize(12);
        psfLMInput->value(40);
        psfLMInput->textsize(12);
      } // Fl_Value_Input* psfLMInput
      { psfNAInput = new Fl_Value_Input(230, 400, 75, 20, "Numerical Aperture:");
        psfNAInput->labelsize(12);
        psfNAInput->value(1);
        psfNAInput->textsize(12);
      } // Fl_Value_Input* psfNAInput
      { psfLambdaInput = new Fl_Value_Input(230, 420, 75, 20, "Wavelength (nm):");
        psfLambdaInput->labelsize(12);
        psfLambdaInput->value(580);
        psfLambdaInput->textsize(12);
      } // Fl_Value_Input* psfLambdaInput
      { Fl_Group* o = new Fl_Group(370, 180, 230, 65, "Coverslip");
        o->box(FL_ENGRAVED_BOX);
        o->labelsize(12);
        o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
        { psfCDRIInput = new Fl_Value_Input(445, 200, 75, 20, "Design:");
          psfCDRIInput->tooltip("Coverslip Design Refractive Index");
          psfCDRIInput->labelsize(12);
          psfCDRIInput->value(1.522);
          psfCDRIInput->textsize(12);
        } // Fl_Value_Input* psfCDRIInput
        { psfCDTInput = new Fl_Value_Input(520, 200, 75, 20);
          psfCDTInput->labelsize(12);
          psfCDTInput->value(0.17);
          psfCDTInput->textsize(12);
        } // Fl_Value_Input* psfCDTInput
        { psfCARIInput = new Fl_Value_Input(445, 220, 75, 20, "Actual:");
          psfCARIInput->tooltip("Coverslip Actual Refractive Index");
          psfCARIInput->labelsize(12);
          psfCARIInput->value(1.522);
          psfCARIInput->textsize(12);
        } // Fl_Value_Input* psfCARIInput
        { psfCATInput = new Fl_Value_Input(520, 220, 75, 20);
          psfCATInput->labelsize(12);
          psfCATInput->value(0.17);
          psfCATInput->textsize(12);
        } // Fl_Value_Input* psfCATInput
        o->end();
      } // Fl_Group* o
      { Fl_Box* o = new Fl_Box(405, 165, 110, 20, "Refractive Index");
        o->labelsize(12);
      } // Fl_Box* o
      { Fl_Box* o = new Fl_Box(515, 165, 85, 20, "Thickness [mm]");
        o->labelsize(12);
      } // Fl_Box* o
      { Fl_Group* o = new Fl_Group(370, 245, 230, 65, "Immersion Medium");
        o->box(FL_ENGRAVED_BOX);
        o->labelsize(12);
        o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
        { psfIMDRIInput = new Fl_Value_Input(445, 265, 75, 20, "Design:");
          psfIMDRIInput->tooltip("Immersion Medium Design Refractive Index");
          psfIMDRIInput->labelsize(12);
          psfIMDRIInput->value(1.515);
          psfIMDRIInput->textsize(12);
        } // Fl_Value_Input* psfIMDRIInput
        { psfIMDTInput = new Fl_Value_Input(520, 265, 75, 20);
          psfIMDTInput->labelsize(12);
          psfIMDTInput->value(0.16);
          psfIMDTInput->textsize(12);
        } // Fl_Value_Input* psfIMDTInput
        { psfIMARIInput = new Fl_Value_Input(445, 285, 75, 20, "Actual:");
          psfIMARIInput->tooltip("Immersion Medium Actual Refractive Index");
          psfIMARIInput->labelsize(12);
          psfIMARIInput->value(1.515);
          psfIMARIInput->textsize(12);
        } // Fl_Value_Input* psfIMARIInput
        { psfIMATInput = new Fl_Value_Input(520, 285, 75, 20);
          psfIMATInput->labelsize(12);
          psfIMATInput->value(0.16);
          psfIMATInput->textsize(12);
        } // Fl_Value_Input* psfIMATInput
        o->end();
      } // Fl_Group* o
      { Fl_Group* o = new Fl_Group(370, 310, 230, 65, "Specimen");
        o->box(FL_ENGRAVED_BOX);
        o->labelsize(12);
        o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
        { psfSRIInput = new Fl_Value_Input(445, 335, 75, 20);
          psfSRIInput->labelsize(12);
          psfSRIInput->value(1.33);
          psfSRIInput->textsize(12);
        } // Fl_Value_Input* psfSRIInput
        o->end();
      } // Fl_Group* o
      { Fl_Group* o = new Fl_Group(370, 375, 230, 65, "Opt. Tube Length");
        o->box(FL_ENGRAVED_BOX);
        o->labelsize(12);
        o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
        { psfOTLDInput = new Fl_Value_Input(445, 410, 75, 20, "Design [mm]");
          psfOTLDInput->labelsize(12);
          psfOTLDInput->value(160);
          psfOTLDInput->textsize(12);
          psfOTLDInput->align(Fl_Align(FL_ALIGN_TOP));
        } // Fl_Value_Input* psfOTLDInput
        { psfOTLAInput = new Fl_Value_Input(520, 410, 75, 20, "Actual [mm]");
          psfOTLAInput->labelsize(12);
          psfOTLAInput->value(160);
          psfOTLAInput->textsize(12);
          psfOTLAInput->align(Fl_Align(FL_ALIGN_TOP));
        } // Fl_Value_Input* psfOTLAInput
        o->end();
      } // Fl_Group* o
      { psfXSizeInput = new Fl_Value_Input(185, 310, 40, 20, "Dimension (x,y,z): ");
        psfXSizeInput->tooltip("Size of x dimension in pixels");
        psfXSizeInput->labelsize(12);
        psfXSizeInput->value(64);
        psfXSizeInput->textsize(12);
      } // Fl_Value_Input* psfXSizeInput
      { psfYSizeInput = new Fl_Value_Input(225, 310, 40, 20);
        psfYSizeInput->tooltip("Size of y dimension in pixels");
        psfYSizeInput->labelsize(12);
        psfYSizeInput->value(64);
        psfYSizeInput->textsize(12);
        psfYSizeInput->align(Fl_Align(FL_ALIGN_TOP));
      } // Fl_Value_Input* psfYSizeInput
      { psfZSizeInput = new Fl_Value_Input(265, 310, 40, 20);
        psfZSizeInput->tooltip("Size of z dimension in pixels");
        psfZSizeInput->labelsize(12);
        psfZSizeInput->value(64);
        psfZSizeInput->textsize(12);
        psfZSizeInput->align(Fl_Align(FL_ALIGN_TOP));
      } // Fl_Value_Input* psfZSizeInput
      { psfXSpacingInput = new Fl_Value_Input(185, 330, 40, 20, "Spacing [um] (x,y,z):");
        psfXSpacingInput->tooltip("Spacing of  x dimension between pixels in micrometers");
        psfXSpacingInput->labelsize(12);
        psfXSpacingInput->value(0.16);
        psfXSpacingInput->textsize(12);
      } // Fl_Value_Input* psfXSpacingInput
      { psfYSpacingInput = new Fl_Value_Input(225, 330, 40, 20);
        psfYSpacingInput->tooltip("Spacing of y dimension between pixels in micrometers");
        psfYSpacingInput->labelsize(12);
        psfYSpacingInput->value(0.16);
        psfYSpacingInput->textsize(12);
        psfYSpacingInput->align(Fl_Align(FL_ALIGN_TOP));
      } // Fl_Value_Input* psfYSpacingInput
      { psfZSpacingInput = new Fl_Value_Input(265, 330, 40, 20);
        psfZSpacingInput->tooltip("Spacing of z dimension between pixels in micrometers");
        psfZSpacingInput->labelsize(12);
        psfZSpacingInput->value(1);
        psfZSpacingInput->textsize(12);
        psfZSpacingInput->align(Fl_Align(FL_ALIGN_TOP));
      } // Fl_Value_Input* psfZSpacingInput
      { psfModelInput = new Fl_Choice(155, 225, 150, 20, "Model: ");
        psfModelInput->tooltip("Select model to use for evaluation");
        psfModelInput->down_box(FL_BORDER_BOX);
        psfModelInput->labelsize(12);
        psfModelInput->textsize(12);
        psfModelInput->menu(menu_psfModelInput);
        psfModelInput->value(0);
      } // Fl_Choice* psfModelInput
      { psfTypeInput = new Fl_Choice(155, 250, 150, 20, "Type: ");
        psfTypeInput->tooltip("Select PSF type for evaluation");
        psfTypeInput->down_box(FL_BORDER_BOX);
        psfTypeInput->labelsize(12);
        psfTypeInput->textsize(12);
        psfTypeInput->menu(menu_psfTypeInput);
        psfTypeInput->value(0);
      } // Fl_Choice* psfTypeInput
      { psfPrecisionInput = new Fl_Choice(155, 275, 150, 20, "Precision: ");
        psfPrecisionInput->tooltip("Select output pixel value data type");
        psfPrecisionInput->down_box(FL_BORDER_BOX);
        psfPrecisionInput->labelsize(12);
        psfPrecisionInput->textsize(12);
        psfPrecisionInput->menu(menu_psfPrecisionInput);
        psfPrecisionInput->value(0);
      } // Fl_Choice* psfPrecisionInput
      { psfSTInput = new Fl_Value_Input(815, 397, 75, 18, "Depth Location (mm):");
        psfSTInput->labelsize(12);
        psfSTInput->textsize(12);
      } // Fl_Value_Input* psfSTInput
      { psfIntervalInput = new Fl_Value_Input(815, 417, 75, 18, "Depth Interval (mm):");
        psfIntervalInput->labelsize(12);
        psfIntervalInput->textsize(12);
      } // Fl_Value_Input* psfIntervalInput
      { psfTotalInput = new Fl_Value_Input(815, 377, 75, 18, "Number of PSF:");
        psfTotalInput->labelsize(12);
        psfTotalInput->minimum(1);
        psfTotalInput->maximum(1024);
        psfTotalInput->value(1);
        psfTotalInput->textsize(12);
      } // Fl_Value_Input* psfTotalInput
      { psfSumCheck = new Fl_Check_Button(815, 465, 20, 20, "Sum over Y:");
        psfSumCheck->box(FL_UP_FRAME);
        psfSumCheck->down_box(FL_DOWN_BOX);
        psfSumCheck->color((Fl_Color)31);
        psfSumCheck->labelsize(12);
        psfSumCheck->align(Fl_Align(FL_ALIGN_LEFT));
      } // Fl_Check_Button* psfSumCheck
      { confocalTab = new Fl_Group(665, 180, 230, 80, "Confocal");
        confocalTab->box(FL_ENGRAVED_BOX);
        confocalTab->labelsize(12);
        confocalTab->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
        confocalTab->deactivate();
        { psfMagYInput = new Fl_Value_Input(815, 231, 75, 19, "Magnification:");
          psfMagYInput->labelsize(12);
          psfMagYInput->value(1);
          psfMagYInput->textsize(12);
        } // Fl_Value_Input* psfMagYInput
        { psfFSizeInput = new Fl_Value_Input(815, 191, 75, 19, "Size");
          psfFSizeInput->labelsize(12);
          psfFSizeInput->textsize(12);
        } // Fl_Value_Input* psfFSizeInput
        { psfDistanceInput = new Fl_Value_Input(815, 211, 75, 19, "Distance:");
          psfDistanceInput->labelsize(12);
          psfDistanceInput->textsize(12);
        } // Fl_Value_Input* psfDistanceInput
        confocalTab->end();
      } // Fl_Group* confocalTab
      { dicTab = new Fl_Group(665, 265, 230, 105, "DIC");
        dicTab->box(FL_ENGRAVED_BOX);
        dicTab->labelsize(12);
        dicTab->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
        dicTab->deactivate();
        { psfAmplitudeRatioInput = new Fl_Value_Input(815, 316, 75, 19, "Amplitude Ratio:");
          psfAmplitudeRatioInput->labelsize(12);
          psfAmplitudeRatioInput->value(0.5);
          psfAmplitudeRatioInput->textsize(12);
        } // Fl_Value_Input* psfAmplitudeRatioInput
        { psfShearInput = new Fl_Value_Input(815, 276, 75, 19, "Shear:");
          psfShearInput->labelsize(12);
          psfShearInput->textsize(12);
        } // Fl_Value_Input* psfShearInput
        { psfBiasInput = new Fl_Value_Input(815, 296, 75, 19, "Bias:");
          psfBiasInput->labelsize(12);
          psfBiasInput->textsize(12);
        } // Fl_Value_Input* psfBiasInput
        { psfRotationAngleInput = new Fl_Value_Input(815, 336, 75, 19, "Rotation Angle:");
          psfRotationAngleInput->labelsize(12);
          psfRotationAngleInput->textsize(12);
        } // Fl_Value_Input* psfRotationAngleInput
        dicTab->end();
      } // Fl_Group* dicTab
      { psfAngleInterval = new Fl_Value_Input(815, 437, 75, 18, "Angle Interval:");
        psfAngleInterval->labelsize(12);
        psfAngleInterval->textsize(12);
      } // Fl_Value_Input* psfAngleInterval
      { Fl_Check_Button* o = psfCenteredCheck = new Fl_Check_Button(815, 485, 20, 20, "Uncentered:");
        psfCenteredCheck->box(FL_UP_FRAME);
        psfCenteredCheck->down_box(FL_DOWN_BOX);
        psfCenteredCheck->color((Fl_Color)31);
        psfCenteredCheck->labelsize(12);
        psfCenteredCheck->align(Fl_Align(FL_ALIGN_LEFT));
        o->value(false);
      } // Fl_Check_Button* psfCenteredCheck
      o->end();
    } // Fl_Group* o
    { xmlInput = new Fl_File_Input(405, 45, 410, 30, "PSF XML Import File:");
      xmlInput->tooltip("Path and filename for PSF XML description");
      xmlInput->labelsize(12);
      xmlInput->textsize(12);
    } // Fl_File_Input* xmlInput
    { Fl_Button* o = new Fl_Button(845, 50, 90, 25, "Browse...");
      o->labelsize(12);
      o->callback((Fl_Callback*)cb_Browse1);
    } // Fl_Button* o
    { Fl_Button* o = new Fl_Button(845, 80, 90, 25, "Open");
      o->tooltip("Read and initialize parameters from selected XML file");
      o->labelsize(12);
      o->callback((Fl_Callback*)cb_Open);
    } // Fl_Button* o
    { psfRealAndImaginaryCheck = new Fl_Check_Button(800, 580, 20, 20, "Generate Real and Imaginary");
      psfRealAndImaginaryCheck->box(FL_UP_FRAME);
      psfRealAndImaginaryCheck->down_box(FL_DOWN_BOX);
      psfRealAndImaginaryCheck->color((Fl_Color)31);
      psfRealAndImaginaryCheck->labelsize(12);
      psfRealAndImaginaryCheck->align(Fl_Align(FL_ALIGN_LEFT));
    } // Fl_Check_Button* psfRealAndImaginaryCheck
    psfWindow->end();
  } // Fl_Double_Window* psfWindow
  PsfXml<double> psfXml;
  		    
  		    std::string file = "lastest.xml";
  		
  		    if (psfXml.open(file) ){
  		       
  			    psfNAInput->value(psfXml.na());
  			    psfLambdaInput->value(psfXml.lambda()*1e6);
  			    psfLMInput->value(psfXml.lm());
  			    psfErrorInput->value(psfXml.absError());
  			    psfSTInput->value(psfXml.ts());
  			    psfSRIInput->value(psfXml.ns());
  			    psfIMDTInput->value(psfXml.tid());
  			    psfIMDRIInput->value(psfXml.nid());
  			    psfIMATInput->value(psfXml.tia());
  			    psfIMARIInput->value(psfXml.nia());
  			    psfCDTInput->value(psfXml.tgd());
  			    psfCDRIInput->value(psfXml.ngd());
  			    psfCATInput->value(psfXml.tga());
  			    psfCARIInput->value(psfXml.nga());
  			    psfOTLDInput->value(psfXml.tld());
  			    psfOTLAInput->value(psfXml.tla());   
  			    psfXSizeInput->value(psfXml.Nxy());
  			    psfYSizeInput->value(psfXml.Nxy());
  			    psfZSizeInput->value(psfXml.Nz()); 
  			    psfXSpacingInput->value(psfXml.deltaXY()*1e3);
  			    psfYSpacingInput->value(psfXml.deltaXY()*1e3);
  			    psfZSpacingInput->value(psfXml.deltaZ()*1e3);
  			    psfModelInput->value(psfXml.model());
  			    interpolateCheck->value(psfXml.evalStr() == "Interpolation");
  			    exactCheck->value(psfXml.evalStr() == "Exact");
  			    psfPrecisionInput->value(psfXml.precision());
  			    psfTypeInput->value(psfXml.type());
  			    
  		    	psfFSizeInput->value(psfXml.fsize());
  		    	psfDistanceInput->value(psfXml.distance());
  		    	psfMagYInput->value(psfXml.magY());
  		    	psfShearInput->value(psfXml.shear());
  		    	psfBiasInput->value(psfXml.bias());
  		    	psfAmplitudeRatioInput->value(psfXml.amplitudeRatio());
  		    	psfRotationAngleInput->value(psfXml.rotation());
  			}
}

PsfGUI::~PsfGUI() {
}

void PsfGUI::show(int argc, char* argv[]) {
  this->psfWindow->show(argc,argv);
}

template<typename T> void PsfGUI::generatePsf() {
  if ( filenameInput->value() == "" || filenameInput->value() == NULL )
  {
      fl_alert("No PSF Output Filename specified");
      return;
  }
  std::string psfname = std::string(filenameInput->value());
  std::string psfsuffix;
  std::string psfprefix;
  size_t i = psfname.rfind('.', psfname.length());
  if ( i != std::string::npos )
  {
      psfprefix = psfname.substr(0,i);
      psfsuffix = psfname.substr(i, psfname.length());
  }
  
  cosm::PsfXml<T> psfXml;
  
  psfXml.na(psfNAInput->value());
  psfXml.lambda(1e-6 *psfLambdaInput->value());
  psfXml.lm(psfLMInput->value());
  psfXml.absError(psfErrorInput->value());
  psfXml.ns(psfSRIInput->value());
  psfXml.tid(psfIMDTInput->value());
  psfXml.nid(psfIMDRIInput->value());
  psfXml.tia(psfIMATInput->value());
  psfXml.nia(psfIMARIInput->value());
  psfXml.tgd(psfCDTInput->value());
  psfXml.ngd(psfCDRIInput->value());
  psfXml.tga(psfCATInput->value());
  psfXml.nga(psfCARIInput->value());
  psfXml.tld(psfOTLDInput->value());
  psfXml.tla(psfOTLAInput->value());
  psfXml.Nxy((int) psfXSizeInput->value());
  psfXml.Nz((int) psfZSizeInput->value());
  psfXml.deltaXY(1e-3 * psfXSpacingInput->value());
  psfXml.deltaZ(1e-3 * psfZSpacingInput->value());
  
  psfXml.model((typename cosm::Psf<T>::Model)psfModelInput->value());
  psfXml.eval(interpolateCheck->value() ? "Interpolation" : "Exact");
  psfXml.type((cosm::PsfType)psfTypeInput->value());
  psfXml.precision((typename cosm::PsfXml<T>::Precision)psfPrecisionInput->value());
  psfXml.sum(psfSumCheck->value() );
  psfXml.centered(!psfCenteredCheck->value() );
  psfXml.fsize(psfFSizeInput->value());
  psfXml.distance(psfDistanceInput->value());
  psfXml.magY(psfMagYInput->value());
  psfXml.shear(psfShearInput->value());
  psfXml.bias(psfBiasInput->value());
  psfXml.amplitudeRatio(psfAmplitudeRatioInput->value());
  psfXml.rotation(psfRotationAngleInput->value());
  psfXml.realAndImag(psfRealAndImaginaryCheck->value());
  
  
  PsfObserver psfObserver(psfProgress);
  std::cout <<" error: "<< psfXml.absError() << std::endl;
  
  
      
  float thickness = psfSTInput->value();
  for ( int i = 0; i < psfTotalInput->value(); i++ )
  {
      std::ostringstream psfindex;
      psfindex << psfprefix << i;
      std::string psffile = (psfTotalInput->value() == 1) ? psfname : (psfindex.str() + psfsuffix);
      std::string xmlfile = (psfTotalInput->value() == 1) ? (psfprefix + ".xml") : (psfindex.str() + ".xml");
      psfXml.file(psffile);
      psfSTInput->value(thickness);
      psfXml.ts(thickness);
      psfXml.save(xmlfile);
      evaluate(psfXml, &psfObserver);
      thickness += psfIntervalInput->value();
  }
}

void PsfGUI::readParameters() {
  PsfXml<double> psfXml;
      
      std::string file = xmlInput->value();
      psfXml.open(file);
         
      psfNAInput->value(psfXml.na());
      psfLambdaInput->value(psfXml.lambda()*1e6);
      psfLMInput->value(psfXml.lm());
      psfErrorInput->value(psfXml.absError());
      psfSTInput->value(psfXml.ts());
      psfSRIInput->value(psfXml.ns());
      psfIMDTInput->value(psfXml.tid());
      psfIMDRIInput->value(psfXml.nid());
      psfIMATInput->value(psfXml.tia());
      psfIMARIInput->value(psfXml.nia());
      psfCDTInput->value(psfXml.tgd());
      psfCDRIInput->value(psfXml.ngd());
      psfCATInput->value(psfXml.tga());
      psfCARIInput->value(psfXml.nga());
      psfOTLDInput->value(psfXml.tld());
      psfOTLAInput->value(psfXml.tla());   
      psfXSizeInput->value(psfXml.Nxy());
      psfYSizeInput->value(psfXml.Nxy());
      psfZSizeInput->value(psfXml.Nz()); 
      psfXSpacingInput->value(psfXml.deltaXY()*1e3);
      psfYSpacingInput->value(psfXml.deltaXY()*1e3);
      psfZSpacingInput->value(psfXml.deltaZ()*1e3);
      psfModelInput->value(psfXml.model());
      interpolateCheck->value(psfXml.evalStr() == "Interpolation");
      exactCheck->value(psfXml.evalStr() == "Exact");
      psfPrecisionInput->value(psfXml.precision());
      psfTypeInput->value(psfXml.type());
      
      filenameInput->value(psfXml.file().c_str());
      
      psfFSizeInput->value(psfXml.fsize());
      psfDistanceInput->value(psfXml.distance());
      psfMagYInput->value(psfXml.magY());
      psfShearInput->value(psfXml.shear());
      psfBiasInput->value(psfXml.bias());
      psfAmplitudeRatioInput->value(psfXml.amplitudeRatio());
      psfRotationAngleInput->value(psfXml.rotation());
}

PsfObserver::PsfObserver(Fl_Progress* prog): PsfUser(), progress_(prog), type_(PsfUser::UNKNOWN) {
}

PsfObserver::~PsfObserver() {
}

void PsfObserver::update( PsfUser::Type type, int count, int total ) {
  if ( type_ != type )
  {
      progress_->value(0);
      type_ = type;
      if ( type == PsfUser::RADIAL )
      {
          progress_->label("Radial Progress");
      }
      else if ( type == PsfUser::COMPLETE )
      {
          progress_->label("Complete Progress");
      }
      else
      {
  	type_ = PsfUser::UNKNOWN;
          progress_->label("Progress");
      }
  }
  progress_->value(100.0*float(count+1)/float(total));
  //progress_->redraw();
  Fl::wait(0.0);
}
