//******************************************************************************
//
//	File:		main.cpp
//
//	Description:	3d hidden line main program
//
//	Written by:	Benoit Schillings
//
//	Copyright 1993, Be Incorporated
//
//	Change History:
//
//	7/31/93		bgs	new today
//	12/14/95	CKH	removing menu stuff
//
//******************************************************************************

#include <time.h>

#include <OS.h>
#include "t3d.h"
#include "shape.h"

#include <math.h>

#ifndef	_APPLICATION_H
#include <Application.h>
#endif

#ifndef	_BITMAP_H
#include <Bitmap.h>
#endif
#ifndef _MENU_ITEM_H
#include <MenuItem.h>
#endif
#ifndef _MENU_H
#include <Menu.h>
#endif
#ifndef _MENU_BAR_H
#include <MenuBar.h>
#endif
#ifndef	_SCROLL_VIEW_H
#include <ScrollView.h>
#endif
#include <stdio.h>
#ifndef _ALERT_H
#include <Alert.h>
#endif

/*------------------------------------------------------------*/
/* Those are the menu item id's of the main window	      */
/*------------------------------------------------------------*/

// #define	ABOUT	0x01
// #define	QUIT	0x02
// #define	DEMO	0x03


/*------------------------------------------------------------*/
T3d	*the_main_view;
/*------------------------------------------------------------*/

class Belogo : public BApplication {

public:
					Belogo ();
			bool	QuitRequested ();
virtual 	void	AboutApplication();
};

/*------------------------------------------------------------*/

	Belogo::Belogo()
	  	  :BApplication ('BE3D')
{
}

void Belogo::AboutApplication()
{
	BAlert *alert = new BAlert("",
						"BeLogo\n A simple Be application\n Benoit Shillings \n Copyright 1995, Be Inc.","OK",NULL,NULL,B_WIDTH_AS_USUAL,B_INFO_ALERT);
alert->Go();


}
/*------------------------------------------------------------*/

bool	Belogo::QuitRequested()
{
	return(TRUE);
}

/*------------------------------------------------------------*/

class	TMainWindow : public BWindow {
public:
		
					TMainWindow(BRect bound,
				    			char *name,
				    			window_type type,
				    			long flags);
virtual		void	MessageReceived(BMessage *an_event);
virtual		bool	QuitRequested();
};

/*------------------------------------------------------------*/


class	TMy3d : public T3d {

			TShape	*main_shape;
			float	alpha, beta, gamma;
			
public:
					TMy3d(BRect r,
						  long flags,
						  long size_x,
						  long size_y);
			void	SetShape(TShape *a_shape);
	virtual	void	MouseMoved(	BPoint where, ulong code, BMessage *a_message);
	virtual	void	Pulse();
};

/*------------------------------------------------------------*/

rgb_color	make_color(long r, long g, long b)
{
	rgb_color	c;
	
	c.red = r;
	c.green = g;
	c.blue = b;
	return(c);
}

/*------------------------------------------------------------*/

void	add_cube(TShape *a_shape,
				 float center_x,
				 float center_y,
				 float center_z,
				 float size)
{
	long	first;
	

	first = 
	a_shape->add_point(center_x-size, center_y-size, center_z-size);	//point 0
	a_shape->add_point(center_x+size, center_y-size, center_z-size);	//point 1
	a_shape->add_point(center_x+size, center_y+size, center_z-size);	//point 2
	a_shape->add_point(center_x-size, center_y+size, center_z-size);	//point 3
		
	a_shape->add_point(center_x-size, center_y-size, center_z+size);	//point 0
	a_shape->add_point(center_x+size, center_y-size, center_z+size);	//point 1
	a_shape->add_point(center_x+size, center_y+size, center_z+size);	//point 2
	a_shape->add_point(center_x-size, center_y+size, center_z+size);	//point 3
		

	a_shape->add_poly(first + 0, first + 1, first + 2, first + 3, make_color(255, 0, 0));
	a_shape->add_poly(first + 4, first + 5, first + 6, first + 7, make_color(255, 255, 0));
	a_shape->add_poly(first + 0, first + 4, first + 7, first + 3, make_color(0, 0, 255));
	a_shape->add_poly(first + 3, first + 7, first + 6, first + 2, make_color(255, 0, 200));
	a_shape->add_poly(first + 1, first + 5, first + 6, first + 2, make_color(50, 130, 255));
}


/*------------------------------------------------------------*/

	TMy3d::TMy3d(BRect r, long flags, long size_x, long size_y) :
	T3d(r, flags, size_x, size_y)
{
	alpha = 0;
	beta = 0;
	gamma = 0;
}

/*------------------------------------------------------------*/


void	TMy3d::Pulse()
{
	BPoint	where;
	ulong	buttons;
	
	alpha += 0.02;
	gamma += 0.03;
	beta += 0.015;

	GetMouse(&where, &buttons);
	clear();
	main_shape->draw(alpha+(where.x/20.0),
					 beta+(where.y/30.0),
					 gamma+(where.y/60.0), 100.0, 100.0);
	Draw();
}

/*------------------------------------------------------------*/


void TMy3d::SetShape(TShape *a_shape)
{
	main_shape = a_shape;
}


/*------------------------------------------------------------*/

void	TMy3d::MouseMoved(BPoint where, ulong code, BMessage *a_message)
{
	clear();
	main_shape->draw(alpha+(where.x/20.0),
					 beta+(where.y/30.0),
					 gamma+(where.y/60.0), 100.0, 100.0);
	Draw();
}

/*------------------------------------------------------------*/

	TMainWindow::TMainWindow(BRect bound, char *name, window_type type, long flags) :
	BWindow(bound, name, type, flags)
{
	BRect		a_rect;
	TMy3d		*my_view;
	TShape		*a_shape;
	long		i, j;


	a_rect.Set(0,0, 199, 199);
	my_view = new TMy3d(a_rect, B_FOLLOW_NONE | B_WILL_DRAW | B_PULSE_NEEDED, 200, 200);
	a_shape = new TShape(my_view);
	
	for (i = -120; i < 120; i+=35) 
	for (j = -120; j < 120; j+=35) {
		add_cube(a_shape, i, j, (i+j)%128, 12);
	}
	
	my_view->SetShape(a_shape);
	AddChild(my_view);
	
	
	Show();
}

/*------------------------------------------------------------*/

bool	TMainWindow::QuitRequested()
{
	be_app->PostMessage(new BMessage(B_QUIT_REQUESTED));
	return(FALSE);
}

/*------------------------------------------------------------*/

void	TMainWindow::MessageReceived(BMessage *an_event)
{

	switch(an_event->what) {
#if 0
		case	QUIT	:
			be_app->PostMessage(new BMessage(B_QUIT_REQUESTED));
			break;
		case	DEMO :
			break;
#endif
 inherited::MessageReceived(an_event);	
}
}

/*------------------------------------------------------------*/

void main()
{
	Belogo		*my_app;
	TMainWindow	*a_window;
	BRect		a_rect;

	set_thread_priority(find_thread(NULL), B_DISPLAY_PRIORITY);
	
	my_app = new Belogo();

	a_rect.Set(100, 100, 300, 300);
	a_window = new TMainWindow(a_rect, "Be3d", B_TITLED_WINDOW, B_NOT_RESIZABLE);
	a_window->SetPulseRate(60);
	my_app->Run();


	delete my_app;
}
