int main(int argc, char** argv) {
	if (argc < 2) {
		printf("Usage: lensview <lens file>\n");
		exit (-1);
	}

	if (!lsystem.Load(argv[1])) {
		printf("Cannot open the lens file: %s.\n", argv[1]);
		exit(-1);
	}
	lvZoom = lvHeight / lsystem.maxAperture() / 3;
	lvZoom = maxv(1, lvZoom);

	glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(lvWidth, lvHeight);
    glutCreateWindow("lensview");
    glutDisplayFunc(lvDisplay);
    glutMotionFunc(lvMotion);
    glutMouseFunc(lvClick);
    glutKeyboardFunc(lvKey);
	glutReshapeFunc(lvResize);
    glutIdleFunc(NULL);

	glMatrixMode(GL_MODELVIEW);  glLoadIdentity();
    glMatrixMode(GL_PROJECTION); glLoadIdentity();	
	glClearColor(BGR, BGG, BGB, 1);
	
	glutMainLoop();
	return (0);
}
int main(int argc, char** argv) {
	if (argc < 2) {
		//printf("Usage: lensview <lens file>\n");
		//exit (-1);
		//argv[1] = ".\\lenses\\dgauss.50mm.dat";
		argv[1] = ".\\lenses\\fisheye.10mm.dat";
		//argv[1] = ".\\lenses\\telephoto.250mm.dat";
		//argv[1] = ".\\lenses\\wide.22mm.dat";
	}


	if (!lsystem.Load(argv[1])) {
		printf("Cannot open the lens file: %s.\n", argv[1]);
		exit(-1);
	}

    printf("1\n");
	lvZoom = lvHeight / lsystem.maxAperture() / 3;
	lvZoom = maxv(1, lvZoom);
    printf("2\n");
	glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(lvWidth, lvHeight);
    glutCreateWindow("lensview");
    glutDisplayFunc(lvDisplay);
    glutMotionFunc(lvMotion);
    glutMouseFunc(lvClick);
    glutKeyboardFunc(lvKey);
	glutReshapeFunc(lvResize);
    glutIdleFunc(NULL);

	glMatrixMode(GL_MODELVIEW);  glLoadIdentity();
    glMatrixMode(GL_PROJECTION); glLoadIdentity();	
	glClearColor(BGR, BGG, BGB, 1);

    printf("3\n");
	glLineWidth(1);
    printf("4\n");
	lsystem.findIntrinsics();
    printf("5\n");
    lsystem.refocus(zDist, -1);
    printf("6\n");
	glutMainLoop();
	return (0);
}
static void lvDisplay(void) {
    glClear(GL_COLOR_BUFFER_BIT);


    applyTransforms();


    glScalef(scale, scale, scale);
	glColor3f(0.25f, 0.25f, 0.25f);
	glLineWidth(2);
	drawLine(-lvWidth-lvTransX, 0, lvWidth-lvTransX, 0);
	drawLine(0, -lvHeight-lvTransY, 0, lvHeight-lvTransY);
	glLineWidth(1);

	lsystem.Draw();		

	// Draw image planes
	glColor3f(1.0, 0.0, 1.0);
	glLineWidth(2);
	drawLine(lsystem.iPlane, lsystem.maxAperture()/2, lsystem.iPlane, -lsystem.maxAperture()/2); 
	drawText(lsystem.iPlane - 1, -lsystem.maxAperture()/2 - 5, SBFONT, "I");
	drawLine(zDist, lsystem.maxAperture()/2, zDist, -lsystem.maxAperture()/2);
	drawText(zDist - 1, -lsystem.maxAperture()/2 - 5, SBFONT, "O");

	// Trace rays through lens system
	glColor3f(0.0, 0.0, 1.0);
	glLineWidth(1);
	
	for (int i = -9; i < 10; i++)
	{
        Ray rayv = Ray(Point(0, iPlaneY, lsystem.iPlane), Vector(0, lsystem.pupil.y/2 * (float) i/9 - iPlaneY, lsystem.pupil.z - lsystem.iPlane));
        Ray& rays = rayv;
        lsystem.Trace(rays, new Ray());
	}
	

	//lsystem.findExitPupil();
	//lsystem.recalAper();
	//lsystem.findF();
	//lsystem.findFp();
	//lsystem.refocus(zDist, -1);

	//Draw principal axes
	glColor3f(0.0, 1.0, 0.0);
	glLineWidth(2);
	drawLine(lsystem.pupil.z, lsystem.pupil.y/2, lsystem.pupil.z, (lsystem.pupil.y+lsystem.maxAperture()) / 2);
	drawLine(lsystem.pupil.z, -lsystem.pupil.y/2, lsystem.pupil.z, (-lsystem.pupil.y-lsystem.maxAperture()) / 2);
	drawText(lsystem.pupil.z, (-lsystem.pupil.y-lsystem.maxAperture()) / 2 - 5, SBFONT, "ep");

	//Draw principal axes
	glColor3f(1.0, 0.0, 0.0);
	glLineWidth(2);
	drawLine(lsystem.p2, lsystem.maxAperture()/2, lsystem.p2, -lsystem.maxAperture()/2);
	drawText(lsystem.p2 - 1, -lsystem.maxAperture()/2 - 5, SBFONT, "P'");
	drawLine(lsystem.p1, lsystem.maxAperture()/2, lsystem.p1, -lsystem.maxAperture()/2);
	drawText(lsystem.p1 - 1, -lsystem.maxAperture()/2 - 5, SBFONT, "P");

	//Draw focal planes
	glColor3f(1.0, 1.0, 0.0);
	drawPoint(5, lsystem.f1, 0);
	drawText(lsystem.f1 - 1, -5, SBFONT, "F");
	drawPoint(5, lsystem.f2, 0);
	drawText(lsystem.f2 - 1, -5, SBFONT, "F'");
	
	glMatrixMode(GL_PROJECTION); glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0, lvWidth, lvHeight, 0);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    drawSquare(0.25f, 0.25f, 0.25f, 0, 0, lvWidth, BARH);
	drawSquare(0.25f, 0.25f, 0.25f, 0, lvHeight, lvWidth, lvHeight-BARH);
	glLoadIdentity();

	gluOrtho2D(-lvWidth, lvWidth, lvHeight, -lvHeight);
	glColor3f(0, 1, 1);
	drawText(-lvWidth + 15, -lvTransY*lvZoom - 8, SBFONT, "+z");
	drawText(lvWidth - 50, -lvTransY*lvZoom - 8, SBFONT, "-z");
	drawText(-lvTransX*lvZoom, -lvHeight + 75, SBFONT, "+y");
	drawText(-lvTransX*lvZoom, lvHeight - 65, SBFONT, "-y");
	
    glColor3f(1, 1, 1);
    const char* mode = lsystem.M == precise ? "precise" : "thick";
	lvText(9, lvHeight-16, SBFONT, 0, "fstop %1.1f (aperture %1.1fmm) | "
		                              "object %1.1fmm | image %1.1fmm | mode: %s", 
									  lsystem.fstop,lsystem.getAperture()->aper,zDist,lsystem.iPlane, mode); 

	lvText(9, 8, SBFONT, 0, "F %1.1fmm | F' %1.1fmm | P %1.1fmm | "
		                    "P' %1.1fmm | exit pupil (%1.1fmm, %1.1fmm)", 
							lsystem.f1,lsystem.f2,lsystem.p1,lsystem.p2,lsystem.pupil.z,lsystem.pupil.y);

	glPopMatrix();
	glutSwapBuffers();
}