#include "spice_plot.h"
#include "hooks.h"


// Application Code

spice_plot::spice_plot(void) : BApplication(MY_SIG)
{
	// Only allow one spice_plot window at a time.
   BList list;
	be_roster->GetAppList(MY_SIG, &list); 
	long app_count = list.CountItems(); 
	if (app_count > 1) {
		PostMessage(B_QUIT_REQUESTED); 
		return;
   }

   spice_plot_window *win;
   spice_plot_view *view;

   win = new spice_plot_window(BRect(25,25,PLOT_WINDOW_SIZE+25,PLOT_WINDOW_SIZE+25));
   view = new spice_plot_view(BRect(0,0,PLOT_WINDOW_SIZE,PLOT_WINDOW_SIZE));

   SetPulseRate(100000);

   win->Lock();
   win->AddChild(view);
   win->Unlock();
   win->Show();
}


void spice_plot::AboutRequested(void)
{
   BAlert *alert;
   long result; 

   alert = new BAlert("", "Ported by Wesley Dungan.\n[e-mail] wesley@idsi.net",
							 "OK", NULL, NULL, 
							 B_WIDTH_AS_USUAL, B_INFO_ALERT);
   result = alert->Go();
}


// Window Code

spice_plot_window::spice_plot_window(BRect frame) : 
   BWindow(frame, "Spice Plot", B_TITLED_WINDOW, B_NOT_RESIZABLE)
{
}


bool spice_plot_window::QuitRequested(void)
{
   be_app->PostMessage(B_QUIT_REQUESTED);
   return(TRUE);
}


// View Code

spice_plot_view::spice_plot_view(BRect frame) :
   BView(frame, NULL, B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_PULSE_NEEDED)
{
   /*
	  BMenuBar *menubar;
	  menubar = new BMenuBar(BRect(0,0,0,0), "MenuBar");

	  BMenu *menu;
	  menu = new BMenu("File");
	  menubar->AddItem(menu);

	  BMenuItem *item; 
	  item = new BMenuItem("About" B_UTF8_ELLIPSIS, new BMessage(B_ABOUT_REQUESTED)); 
	  item->SetTarget(be_app); 
	  menu->AddItem(item);

	  AddChild(menubar);
	  */
   offview = new BView(BRect(0,0,PLOT_WINDOW_SIZE,PLOT_WINDOW_SIZE), NULL, B_FOLLOW_ALL_SIDES, B_WILL_DRAW);
   plot_data = new BBitmap(BRect(0,0,PLOT_WINDOW_SIZE,PLOT_WINDOW_SIZE), B_COLOR_8_BIT, true);

   plot_data->Lock();
   plot_data->AddChild(offview);
   plot_data->Unlock();
}


void spice_plot_view::Draw(BRect update_area)
{
   DrawBitmap(plot_data, BPoint(0, 0));
}


void spice_plot_view::Pulse(void)
{
   plot_data->Lock();

   port_id id;
   if ((id = find_port("spice_plot_port")) == B_NAME_NOT_FOUND) {
      be_app->PostMessage(B_QUIT_REQUESTED);
      return;
   }
	
   ssize_t size;
   enum BeUI_MessageCode code;
   struct BeUI_Message msg;

   while ((size = port_buffer_size_etc(id, B_TIMEOUT, 1)) >= B_NO_ERROR) {
      read_port(id, (int32 *)&code, &msg, size);

      switch (code) {
      case Quit :
			be_app->PostMessage(B_QUIT_REQUESTED);
			return;
      case Clear :
			Window()->Lock();
			offview->SetHighColor(offview->LowColor());
			offview->FillRect(offview->Frame());
			offview->SetHighColor(0,0,0);
			Window()->Unlock();
			break;
      case DrawLine :
			//printf("DrawLine: head=(%d,%d)  tail=(%d,%d)\n", msg.x1, msg.y1, msg.x2, msg.y2);

			Window()->Lock();
			offview->StrokeLine(BPoint(msg.x1, msg.y1), BPoint(msg.x2, msg.y2));
			Window()->Unlock();
			break;
      case Arc :
			//printf("Arc: center=(%d,%d)  radius=%d   Theta1=%f  Theta2=%f\n",
			//	  msg.x1, msg.y1, msg.radius, msg.theta1, msg.theta2);
		
			Window()->Lock();
			offview->StrokeArc(BPoint(msg.x1, msg.y1), msg.radius, msg.radius, 
									 msg.theta1, msg.theta2-msg.theta1);
			Window()->Unlock();
			break;
      case Text :
			//printf("Text: text='%s'  location=(%d,%d)\n", msg.text, msg.x1, msg.y1);
	     
			Window()->Lock();
			offview->DrawString(msg.text, BPoint(msg.x1, msg.y1));
			Window()->Unlock();
			break;
      case SetLineStyle :
         //printf("SetLinestyle: linestyleid=%d\n", linestyleid);
         break;
      case SetColor :
         //printf("SetColor: colorid=%d\n", colorid);
         Window()->Lock();
         offview->SetHighColor(color_table[msg.x1%8]);
         Window()->Unlock();
         break;
      default :
			printf("ERROR: Unknown BeUI_MessageCode %d\n", code);
      }
   }

   offview->Sync();
   plot_data->Unlock();

   Draw(BRect(0,0,0,0));
}
