<raw file>
/************************************************************************

   Program Geometry: displays a molecule from a *.geo file to screen
   with interactive perspective

   Copyright: Douglas B. Cameron, AlphaSquared.com, 2002.

   To do:
      - smooth bond connection to atoms at correct point

  11/6/02 - Added 3D Marching cubes visualization

*************************************************************************/

#include "Strng.h"
#include "Desktop.h"
#include "Win32\ConsoleStream.h"
#include "Coutlog.h"
#include "System.h"

#include "..\Chem\GUI\MolViewControl.h"
#include "..\Chem\GUI\MolecularField.h"

using namespace AlphaSquaredGUI;


Win32ConsoleOStream console;
StreamReassignment  reassign( cout, console );


struct MolViewProgram: public AlphaSquaredGUI::Desktop {

  MolViewProgram( InterfaceImp* interfaceImp )
    : Desktop( "Molecule Viewer", interfaceImp ),
      molecule(),
      openFileButton( "open new file", this, &MolViewProgram::OpenNewFile, this ),
      pageManager( "Views", this ),
      standardView( "Molecule View", GrantRef(molecule), this),
      surfaceView(  "Surface View",  GrantRef(molecule), this ) {

    surfaceView.SetVisible( false );

    CommandArgs args = interfaceImp->CommandLine();

    cout << "Usage: geo [in_filename]" << newl;
    cout << "  File format:    'DNA Structure, Ha!' // title" << newl;
    cout << "                  '4.0'                // max bond length" << newl;
    cout << "       repeat:    'AN x y z'           // atomic number or symbol, xyz-coordinates" << newl;
    cout << newl;
    cout << "Geometry++ V5.0 DBC October 25, 2002\n";
    cout << "Geometry++ V4.2 DBC November 12, 1994\n";
    cout << "Geometry++ V4.1 DBC December 14, 1993\n";
    cout << "Geometry++ V4.0 DBC May 29, 1993\n";
    cout << "Geometry V3.0 DBC December 17, 1991\n";

    Filename filename;

    if (args.Size()>0) {
      filename.Copy( args(0) );
      if ( !filename.HasExtension() )
        filename.SetExtension( "geo" );
    }

    OpenFile( filename );

    pageManager.AddButtonForAutoPage( "Standard View", &standardView, 50/*vertical size*/ );
    pageManager.AddButtonForAutoPage( "Volume   View", &surfaceView,  50/*vertical size*/ );

    openFileButton .SetLocation( Rectanglef( 0.800f, 0.995f, 0.995f, 0.950f ) );
    }

  void OpenFile( String filename ) {
    // if filename = "" then prompts user

    if (filename.Size()==0) {
      tryAgain:

      bool ok;
      const bool allowDirChange = true;
      GetFilenameToOpen( &ok, String("Open geometry file"), &filename,
                         String("Geo files"), String("*.geo"), allowDirChange );
      if (!ok)
        return;
    }

    try {

      molecule.Read(filename);

    } catch ( AlphaSquared::XMessage& m ) {
      String msg(m.Get());
      msg << "\n Error reading file. Try another.";
      WarnError( msg );
      goto tryAgain;
    } catch ( const char* m ) {
      String msg(m);
      msg << "\n Error reading file. Try another.";
      WarnError( msg );
      goto tryAgain;
    } catch( const String& m ) {                                      // added 10/18/02
      String msg(m);
      msg << "\n Error reading file. Try another.";
      WarnError( msg );
      goto tryAgain;
    } catch (...) {
      WarnError( "Error reading file. Try another." );
      goto tryAgain;
    }

    standardView.MoleculeChanged();
    surfaceView.MoleculeChanged();
    }

  void OpenNewFile() {
    OpenFile( String() );
    standardView.Update();
    surfaceView.Update();
    }

  public:
    Molecule                    molecule;
    PushButtonByMF<MolViewProgram>  openFileButton;
    VerticalPageManager         pageManager;
    StandardMolView             standardView;
    MolecularSurfaceAndControls surfaceView;
};


CtrlPointer<AbstractProgram> AlphaSquaredGUI::ProgramMain( InterfaceImp& implementation ) {
  return CtrlPointer<AbstractProgram>( TakeControl, new MolViewProgram( &implementation ) );
}