#define WIN32_LEAN_AND_MEAN  // just say no to MFC
#include <windows.h>   // include all the windows headers
#include <windowsx.h>  // include useful macros
#include <stdio.h>
#include <math.h>
#include "headers.h"
#include<iostream.h>
#include<fstream.h>
int x,y,r,g,b;
xyz nor;
ray_tracer trace;


#define WINDOW_CLASS_NAME "WINCLASS1"
HDC                    hdc; 



LRESULT CALLBACK WindowProc(HWND hwnd,
                  UINT msg,
                            WPARAM wparam,
                            LPARAM lparam)
{

PAINTSTRUCT    ps;  
 


switch(msg)
    {
    case WM_CREATE:
        {
   

    return(0);
    } break;

    case WM_PAINT:
    {

    hdc = BeginPaint(hwnd,&ps);

        EndPaint(hwnd,&ps);

  
    return(0);
    } break;
    case WM_DESTROY:
    {

    PostQuitMessage(0);


    return(0);
    } break;
	case WM_SIZE:
        {
			y=0;
			InvalidateRect(hwnd,NULL,FALSE);


    return(0);
    } break;
	case WM_ACTIVATE:
        {
			y=0;
			InvalidateRect(hwnd,NULL,FALSE);
   

 
    return(0);
    } break;
    default:break;

    } 


return (DefWindowProc(hwnd, msg, wparam, lparam));

} 

// WINMAIN //

int WINAPI WinMain(HINSTANCE hinstance,
            HINSTANCE hprevinstance,
            LPSTR lpcmdline,
            int ncmdshow)
{

WNDCLASSEX winclass; 
HWND       hwnd;      
MSG          msg;      


winclass.cbSize  = sizeof(WNDCLASSEX);
winclass.style     = CS_DBLCLKS | CS_OWNDC |
                     CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc    = WindowProc;
winclass.cbClsExtra     = 0;
winclass.cbWndExtra     = 0;
winclass.hInstance      = hinstance;
winclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground  = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName   = NULL;
winclass.lpszClassName  = WINDOW_CLASS_NAME;
winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);


if (!RegisterClassEx(&winclass))
    return(0);


if (!(hwnd = CreateWindowEx(NULL, // extended style
                  WINDOW_CLASS_NAME,   // class
                 "Ray Trace Renderer v 1.1", // title
                  WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                  0,0,        // initial x,y
                  600,600,  // initial width, height
                  NULL,        // handle to parent
                  NULL,        // handle to menu
                  hinstance,// instance of this application
                  NULL)))    // extra creation parms
return(0);


trace.set_up();
color point_color,subpix_color;
xyz current_ray,sub_ray;
double dx,dy,temp_x,temp_y;
double subpix_r,subpix_g,subpix_b;
xyz first_ray,scrx,scry;
first_ray.x=(trace.start_ray)->x;
first_ray.y=(trace.start_ray)->y;
first_ray.z=(trace.start_ray)->z;
scrx.x=(trace.s_xaxis)->x;
scrx.y=(trace.s_xaxis)->y;
scrx.z=(trace.s_xaxis)->z;
scry.x=(trace.s_yaxis)->x;
scry.y=(trace.s_yaxis)->y;
scry.z=(trace.s_yaxis)->z;


y=0;
	
DWORD start_time;


while(GetMessage(&msg,NULL,0,0))
      {

      TranslateMessage(&msg);


      DispatchMessage(&msg);
	


	  if(y==0)
	  start_time = GetTickCount();
	  if(y<=trace.ver_res)
	  {
		  hdc = GetDC(hwnd);
		  for(x=40;x<=(trace.hor_res)+40;x++)
		  {

			if(trace.super_sampling_type==0)
			{
			current_ray.x=(first_ray.x)+((x)*(scrx.x))-((y)*(scry.x));
			current_ray.y=(first_ray.y)+((x)*(scrx.y))-((y)*(scry.y));
			current_ray.z=(first_ray.z)+((x)*(scrx.z))-((y)*(scry.z));
			current_ray.normalize();
			point_color=(trace.get_intersection(-1,&current_ray,&(trace.camera)));


			
			if(trace.flag==1 && trace.super_sampling_type ==0)
			{
			
				int i;
				for(i=0;i<=4;i++)
				{
			subpix_r=0;
			subpix_g=0;
			subpix_b=0;

			for(dy=0;dy<trace.samples;dy++)
				for(dx=0;dx<trace.samples;dx++)
				{
				
					temp_x=trace.magnitude_x/trace.samples;
					temp_y=trace.magnitude_y/trace.samples;
			sub_ray.x=(first_ray.x)+((x-i+(temp_x)*dx)*(scrx.x))-((y+(temp_y)*dy)*(scry.x));
			sub_ray.y=(first_ray.y)+((x-i+(temp_x)*dx)*(scrx.y))-((y+(temp_y)*dy)*(scry.y));
			sub_ray.z=(first_ray.z)+((x-i+(temp_x)*dx)*(scrx.z))-((y+(temp_y)*dy)*(scry.z));
			sub_ray.normalize();
			subpix_color=trace.get_intersection(-1,&sub_ray,&(trace.camera));

				

			subpix_r+=subpix_color.r;
			subpix_g+=subpix_color.g;
			subpix_b+=subpix_color.b;
			}
				point_color.r=subpix_r/(trace.samples*trace.samples);
	        	point_color.g=subpix_g/(trace.samples*trace.samples);
				point_color.b=subpix_b/(trace.samples*trace.samples);
			r=                     point_color.gamma_correct_r();
			g=	                   point_color.gamma_correct_g();
			b=	                   point_color.gamma_correct_b();

			COLORREF color = RGB(r,g,b);

            SetPixel(hdc, x-i,y, color);

			

			}
				
				trace.flag=0;
			}
			else
			{

			r=                     point_color.gamma_correct_r();
			g=	                   point_color.gamma_correct_g();
			b=	                   point_color.gamma_correct_b();

			COLORREF color = RGB(r,g,b);
            SetPixel(hdc, x,y, color);
			}
			}
			if(trace.super_sampling_type==1)
			{
			subpix_r=0;
			subpix_g=0;
			subpix_b=0;
			for(dy=0;dy<trace.samples;dy++)
				for(dx=0;dx<trace.samples;dx++)
				{
					temp_x=trace.magnitude_x/trace.samples;
					temp_y=trace.magnitude_y/trace.samples;
			current_ray.x=(first_ray.x)+((x+(temp_x)*dx)*(scrx.x))-((y+(temp_y)*dy)*(scry.x));
			current_ray.y=(first_ray.y)+((x+(temp_x)*dx)*(scrx.y))-((y+(temp_y)*dy)*(scry.y));
			current_ray.z=(first_ray.z)+((x+(temp_x)*dx)*(scrx.z))-((y+(temp_y)*dy)*(scry.z));
			current_ray.normalize();
			subpix_color=trace.get_intersection(-1,&current_ray,&(trace.camera));

				

			subpix_r+=subpix_color.r;
			subpix_g+=subpix_color.g;
			subpix_b+=subpix_color.b;
			}
				
				point_color.r=subpix_r/(trace.samples*trace.samples);
	        	point_color.g=subpix_g/(trace.samples*trace.samples);
				point_color.b=subpix_b/(trace.samples*trace.samples);


		
			r=                     point_color.gamma_correct_r();
			g=	                   point_color.gamma_correct_g();
			b=	                   point_color.gamma_correct_b();

			COLORREF color = RGB(r,g,b);
            SetPixel(hdc, x,y, color);
			}

		  }
			
			y++;
	  }
			if(y%50==0)
			{ 
	/*	char Buffer1[128];
		sprintf(Buffer1, "ray x %e ",nor.x);
		TextOut(hdc,206,410,Buffer1,strlen(Buffer1));

		char Buffer2[128];
		sprintf(Buffer2, "ray y %e",nor.y);
		TextOut(hdc,206,450,Buffer2,strlen(Buffer2));

		char Buffer3[128];
		sprintf(Buffer3, "ray z %e",nor.z);
		TextOut(hdc,206,480,Buffer3,strlen(Buffer3));
*/
		char Buffer[128];
		sprintf(Buffer, "RENDERING LINE %d", y);
		TextOut(hdc,236,520,Buffer,strlen(Buffer));
		
			}
			if(y==512)
			{
				DWORD diff=GetTickCount()-start_time;
			char Buffert[128];
			sprintf(Buffert, "Time Elapsed: %d milliseconds", diff);
			TextOut(hdc,206,540,Buffert,strlen(Buffert));
			TextOut(hdc,236,520,"      Picture Complete     ",strlen("      Picture Complete     "));
			}
				ReleaseDC(hwnd, hdc);
				InvalidateRect(hwnd,NULL,FALSE);
	  


}

return(msg.wParam);

} 
