/*
# pdbView : $Revision$  
# $Date$ 
# Created by $Author$
# Usage : pdbView
# Attention
#   $Loccker$
#  	$State$ 
#
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stream.h>
#include "vtk.h"

#include "eosAxisSource.hh"
#include "./eosRuler.hh"              
#include "eosRuler.cc"

#define GLOBAL_DECLARATION
#include "../inc/config.h"

#define DEBUG
#include "genUtil.h"
#include "pdbFile.h"

#include "vtkTextMapper.h"
#include "vtkPicker.h"

//temp
#include "vtkImageGridSource.h"


vtkCellPicker* picker;


int* filePdb[100];
int* fileActor[100];
int* fileMapper[100];


void annotatePick(void* arg){
 
    float x,y,z,xp,yp,zp;
    float* pickPos;
    float* selPt;

    //vtkActor* pickActor;
    //vtkPolyDataMapper* pickMapper;

    vtkActor* pickActor;
    vtkAbstractMapper3D* pickMapper;

    vtkRenderer* ren = (vtkRenderer*)arg;

    //vtkTextSource* text = vtkTextSource::New();
    //vtkActor* textActor = vtkActor::New();
    //vtkActor2D* textActor = vtkActor2D::New();
    //vtkTextMapper* textMapper = vtkTextMapper::New();
    
    
    vtkFollower* textActor = vtkFollower::New();
    vtkPolyDataMapper* textMapper = vtkPolyDataMapper::New();
    vtkVectorText* text = vtkVectorText::New();



    //-1=nothings was picked
   if( (picker->GetCellId()) < 0)
     {
       
       textActor->VisibilityOff();
       
     }else{
       
       selPt = picker->GetSelectionPoint();
       x = selPt[0];
       y = selPt[1];
       z = selPt[2];
       
       pickPos = picker->GetPickPosition();
       
       xp = pickPos[0];
       yp = pickPos[1];
       zp = pickPos[2];
       
       pickActor = picker->GetActor();
       pickMapper = picker->GetMapper();


       cout << form("address+++A=%d,M=%d\n",pickActor , pickMapper);

       int j;
       for(j=0;j<100;j++)
	 {
	   vtkPolyDataMapper* fMapper = (vtkPolyDataMapper*)fileMapper[j];
	   if(pickMapper == fMapper)
	     {

       cout << form("PDB==%s\n",*pdb[j]);
	     }
	 }


       //Now Test       
       
       text->SetText(form("%f,%f,%f",xp,yp,zp));
       textMapper->SetInput(text->GetOutput());
       
              
       textActor->SetMapper(textMapper);
       textActor->SetScale(0.1,0.1,0.1);


       //cout << form("%f,%f,%f\n",x , y ,z);

       textActor->SetPosition(xp,yp,zp);


       //textActor->SetPosition(0,2,3);
       
       //  textActor->SetPosition(x,y,z);


       textActor->SetCamera(ren->GetActiveCamera());


       
       ren->AddActor(textActor);
       
       
       
       
       /*
	 
       //vtkTextSource* text = vtkTextSource::New();
       //vtkActor* textActor = vtkActor::New();
       //vtkPolyDataMapper* textMapper = vtkPolyDataMapper::New();
       textMapper->SetInput(form("%f,%f,%f",xp,yp,zp));
       
       */

	//True
	/*
       textMapper->SetInput(form("%f,%f,%f",xp,yp,zp));
	textMapper->ShadowOn();
	textActor->SetMapper(textMapper);
	textActor->SetPosition(x,y);
	ren->AddActor2D(textActor);
	*/	


     }
   
   
   
   
   
  }






/*
Example:
typedef struct lpdbViewInfo {
	float a;
	int   b;
} lpdbViewInfo;

typedef enum lpdbViewMode {
	a=0,
	b=1
} lpdbViewMode;
*/


int
main(int argc, char* argv[]) 
{
  eosAxisSource axisClass;
  eosAxisSource axisClass2;
  
  eosRuler ruler;
  
  
  pdbViewInfo info;
  pdbFile pdb;
  pdbFile* ppdb;

  ppdb = &pdb;
  
  init0(&info);
  argCheck(&info, argc, argv);
  init1(&info);
  
  DEBUGPRINT("Program Start\n");
  cout << "start C++\n";
  pdbFileRead(info.fptIn, &pdb);
  
  vtkRenderer *ren = vtkRenderer::New();
  vtkRenderWindow *renWindow = vtkRenderWindow::New();
  renWindow->AddRenderer(ren);
  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWindow);
  
  //axisClass.Draw(ren);
  
  //axisClass2.SetScale(2);
  // axisClass2.SetLength(2);
  //axisClass2.Draw(ren);
  
  //ruler.SetDivision(1.5);
  //ruler.SetScaleLength(15);
  //ruler.Draw(ren);
  
  //CreateMoleculeModel

  picker = vtkCellPicker::New();
  picker->SetEndPickMethod(&annotatePick,ren);
  iren->SetPicker(picker);



  //SetText
  vtkTextMapper* tMapper = vtkTextMapper::New();
  tMapper->SetInput("testShow");
  tMapper->ShadowOn();

  vtkActor2D* tActor = vtkActor2D::New();
  tActor->SetMapper(tMapper);
  tActor->SetPosition(0,0);

  ren->AddActor2D(tActor);


  //Axes

  vtkAxes* axes = vtkAxes::New();
  axes->SetOrigin(0,0,0);
  vtkPolyDataMapper* axesMapper = vtkPolyDataMapper::New();
  axesMapper->SetInput(axes->GetOutput());
  vtkActor* axesActor = vtkActor::New();
  axesActor->SetMapper(axesMapper);

  //vtkVectorText* atext = vtkVectorText::New();
  //atext->SetText("I want to Money!!");
  //vtkPolyDataMapper* atextMapper = vtkPolyDataMapper::New();
  //atextMapper->SetInput(atext->GetOutput());

  //vtkFollower* atextActor = vtkFollower::New();
  //atextActor->SetMapper(atextMapper);
  //atextActor->SetScale(0.2,0.2,0.2);
  //atextActor->SetPosition(0,-0.1,1);

  ren->AddActor(axesActor);
  //ren->AddActor(atextActor);






    double moleculeRadius = 1.6;
    float x,y,z;
    int resolution = 4;
    int j=0;
    vtkAssembly* moleData = vtkAssembly::New();

    pdbFileTop(ppdb);
    while(1){
       if(pdbFileIsCA(ppdb)){
	 pdbFileCoordGet(ppdb, &x, &y, &z);

	 vtkSphereSource* molecule = vtkSphereSource::New();
	 molecule->SetRadius(moleculeRadius);
	 molecule->SetThetaResolution(resolution);
	 molecule->SetPhiResolution(resolution);
	 molecule->SetCenter(0,0,0);
	 vtkPolyDataMapper* moleculeMapper = vtkPolyDataMapper::New();
	 moleculeMapper->SetInput(molecule->GetOutput());
	 vtkActor* moleculeActor= vtkActor::New();
	 moleculeActor->SetMapper(moleculeMapper);
	 moleculeActor->SetPosition(x,y,z);
	 moleculeActor->GetProperty()->SetColor(0.5,0.5,0.5);
	 moleData->AddPart(moleculeActor);

	 fileActor[j]=moleculeActor;
	 fileMapper[j]=moleculeMapper;
	 filePdb[j]=ppdb;
  cout << form("AddRess---A=%d,M=%d\n",moleculeActor , moleculeMapper);

  j=j+1;
       }     
           if(pdbFileEnd(ppdb)){
	 break;
       } else {
	 pdbFileNext(ppdb);
       }
  }
  
  ren->AddActor(moleData);  



  
  //Cube
  vtkCubeSource *cube = vtkCubeSource::New();
  cube->SetCenter(0,0,0);
  cube->SetXLength(5);
  cube->SetYLength(5);
  cube->SetZLength(5);
  //cube->SetBounds(0.0,0.5,0.0,0.3,0.0,0.2);
  vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New();
  cubeMapper->SetInput(cube->GetOutput());
  vtkActor *cubeActor = vtkActor::New();
  cubeActor->SetMapper(cubeMapper);
  cubeActor->GetProperty()->SetOpacity(0.5);
  cubeActor->GetProperty()->SetColor(0.4,0.4,0.7);
  


    //assign our actor to the renderer

    //ren->AddActor(coneActor);
    //ren->AddActor(coneActor2);
    //ren->AddActor(pointActor);
    ren->AddActor(cubeActor);
    //ren->AddActor(lineXActor);
    //ren->AddActor(lineYActor);
    //ren->AddActor(lineZActor);
    //ren->AddActor(axisActor);
    //ren->AddActor(arrowActor);

    //ren->AddActor(ruleActor);

    ren->SetBackground(0,0,0);

    ren->ResetCamera();

    renWindow->PolygonSmoothingOff();
     renWindow->PointSmoothingOff();
    renWindow->LineSmoothingOff();
  

    //renWindow->PolygonSmoothingOff();


    renWindow->SetSize(400,400);

    //draw the resulting scene
    renWindow->Render();

    //Begin mouse interaction
    iren->Start();

    //picker->Pick( 200, 200, 0, ren);


    //mine
    //vtkLine *line = vtkLine::New();
    //float lineCoords[2][1];

    //line->GetPointIds()->SetId(0,0);
    //line->GetPointIds()->SetId(1,1);

    //lineCoords[0][0]=.25;
    //lineCoords[1][0]=.75;





	exit(EXIT_SUCCESS);
}

void
additionalUsage()
{
	fprintf(stderr, "----- Additional Usage -----\n");
}
