// Program:			TestTriangle Version 1
// Source File:	ttri1.cpp
// Date Written:	11/22/00
// Team members:	Srikanth Batchu, Chris Kelly, Chris Brooks

// This program developes a class for triangles.  The program initializes a 
// triangle with 3 parameters and displays it.  The triangle is then moved
//	a distance and then redisplays again after being moved.  The perimeter
//	and area are shown for the current triangle along with the two triangles.  
//
//	The program then prompts the user to click three points for the three
//	vertices of a triangle.  The triangle is then displayed and the x,y
//	coordinates are displayed at each vertice of the triangle.
//
//	The last section then displays the triangle again with the parameter and area
//	values only.

   using namespace std;
#include "ccc_win.cpp"
#include <cmath>
#include "BoolOps.h"
#include "XGrphP1.h"

   class Triangle
   {
   private:
      Point vertex0, vertex1, vertex2;
   
   public:
   
   // Initialization
   
      Triangle (Point v0, Point v1, Point v2);
   	// Initialize the current triangle, setting the values of the 3 vertices
   
      Triangle();
   	// Intitializes the current triangle, setting the values of the 3 vertices to (0.0,0.0)
   
   // Access
      Point get_vertex0 () const;
      Point get_vertex1 () const;
      Point get_vertex2 () const;
   
   // Change
      void move (double dx, double dy);
   
   // Misc
      double perimeter () const;
      double area () const;
   
   // Input/Output
      void display () const;
      void get (string p);																																																																																																														
   
   };

// Function declarations

   void xgio_point_display_coordinates (Point p);
   // Display a message including the coordinates of p.
   //
   // Post: A message is displayed giving the coordinates of p

   void xgio_pause ();
   // Pause until the user presses the <Enter> key.
   //
   // Post: The program is paused until the user pressesthe <Enter> key

   int main()
   {
      Triangle tri (Point (0.0, 0.0), Point (0.0, 3.0), Point (4.0, 3.0));
   
   // Display initialization message
      Point im1_start (-6.0, -5.0), im2_start (-6.0, -6.0);
      string im1_text = "The triangle has been constructed with",
         im2_text = "vertex1 (0.0, 0.0) vertex2 (0.0, 3.0) and vertex3 (4.0, 3.0).";
      Message initialization_message_1 (im1_start, im1_text),
         initialization_message_2 (im2_start, im2_text);
      cwin << initialization_message_1 << initialization_message_2;
   
      tri.display ();
      tri.move (1.0, -2.0);
   
   // Display move message      
      Point mm1_start (-6.0, -8.0), mm2_start (-6.0, -9.0);
      string mm1_text = "Then the triangle has been moved 1.0 units to",
         mm2_text = " the right and 2.0 units down.";
      Message move_message_1 (mm1_start, mm1_text), move_message_2 (mm2_start, mm2_text);
      cwin << move_message_1 << move_message_2;
   
      tri.display ();
   
      double triangle_perimeter = tri.perimeter ();
      double triangle_area = tri.area ();
   
   // Display perimeter and area messages
      Point pm1_start (3, -1);  
      Point pm2_start (6, -1);
      Message perimeter_message_1 (pm1_start, "Perimeter: "),
         perimeter_message_2 (pm2_start, triangle_perimeter);
      cwin << perimeter_message_1 << perimeter_message_2;
   
      //Point am1_start = pm1_start; am1_start.move (0.0, -1.0);
      Point am1_start (3, -2);
      //Point am2_start = am1_start; am2_start.move (2.0, 0.0);
      Point am2_start (6, -2);
      Message area_message_1 (am1_start, "Area: "), area_message_2 (am2_start, triangle_area);
      cwin << area_message_1 << area_message_2;
   
      xgio_pause (); cwin.clear ();
   
      tri.get ("Click on the vertices when prompted.");
   
   // Display the triangle, its vertices, and their coordinates
   
      tri.display ();
      cwin << tri.get_vertex0 () << tri.get_vertex1 () << tri.get_vertex2 ();
      xgio_point_display_coordinates (tri.get_vertex0 ());
      xgio_point_display_coordinates (tri.get_vertex1 ());
      xgio_point_display_coordinates (tri.get_vertex2 ());
   
      xgio_pause (); cwin.clear ();
   
      tri.display ();
   
      triangle_perimeter = tri.perimeter ();
      triangle_area = tri.area ();   
   
   // Display perimeter and area messages
      pm2_start = pm1_start; pm2_start.move (4.0, 0.0);
      perimeter_message_1 = Message (pm1_start, "Perimeter: ");
      perimeter_message_2 = Message (pm2_start, triangle_perimeter);
      cwin << perimeter_message_1 << perimeter_message_2;
   
      am1_start = pm1_start; am1_start.move (0.0, -1.0);
      am2_start = am1_start; am2_start.move (4.0, 0.0); 
      area_message_1 = Message (am1_start, "Area: ");
      area_message_2 = Message (am2_start, triangle_area);
      cwin << area_message_1 << area_message_2;
   
      return 0;
   }


   Triangle::Triangle (Point v0, Point v1, Point v2)
   : vertex0 (v0), vertex1 (v1), vertex2 (v2)
   {
   }


   Triangle :: Triangle ()
   {
      Point v0(0.0, 0.0);
      Point v1(0.0, 0.0);
      Point v2(0.0, 0.0);
   }


   Point Triangle :: get_vertex0 () const
   {
      return vertex0;
   }

   Point Triangle :: get_vertex1 () const
   {
      return vertex1;
   }

   Point Triangle :: get_vertex2 () const
   {
      return vertex2;
   }	

   void Triangle :: move( double dx, double dy )
   {
      vertex0.move (dx, dy);
      vertex1.move (dx, dy);
      vertex2.move (dx, dy);
   }			


   double Triangle :: perimeter () const
   {
      double result;
   
   	// Compute dx and dy for line segments
      double dx_seg1 = vertex0.get_x () - vertex1.get_x ();
      double dx_seg2 = vertex1.get_x () - vertex2.get_x ();
      double dx_seg3 = vertex2.get_x () - vertex0.get_x ();
      double dy_seg1 = vertex0.get_y () - vertex1.get_y ();
      double dy_seg2 = vertex1.get_y () - vertex2.get_y ();
      double dy_seg3 = vertex2.get_y () - vertex0.get_y ();
   
   	// Compute perimeter for each of 3 line segments
      double perim_dist_seg1 = sqrt ((dx_seg1 * dx_seg1) + (dy_seg1 * dy_seg1));
      double perim_dist_seg2 = sqrt ((dx_seg2 * dx_seg2) + (dy_seg2 * dy_seg2));
      double perim_dist_seg3 = sqrt ((dx_seg3 * dx_seg3) + (dy_seg3 * dy_seg3));
   
      double perimeter = perim_dist_seg1 + perim_dist_seg2 + perim_dist_seg3;
      result = perimeter;
   
      return result;
   }


   double Triangle :: area () const
   {
      double result;
   
   	// Compute dx and dy for line segments
      double dx_seg1 = vertex0.get_x () - vertex1.get_x ();
      double dx_seg2 = vertex1.get_x () - vertex2.get_x ();
      double dx_seg3 = vertex2.get_x () - vertex0.get_x ();
      double dy_seg1 = vertex0.get_y () - vertex1.get_y ();
      double dy_seg2 = vertex1.get_y () - vertex2.get_y ();
      double dy_seg3 = vertex2.get_y () - vertex0.get_y ();
   
   	// Compute perimeter for each of 3 line segments
      double perim_dist_seg1 = sqrt ((dx_seg1 * dx_seg1) + (dy_seg1 * dy_seg1));
      double perim_dist_seg2 = sqrt ((dx_seg2 * dx_seg2) + (dy_seg2 * dy_seg2));
      double perim_dist_seg3 = sqrt ((dx_seg3 * dx_seg3) + (dy_seg3 * dy_seg3));
   
      double s = (perim_dist_seg1 + perim_dist_seg2 + perim_dist_seg3) / 2;
      double area = sqrt ((s* (s - perim_dist_seg1) * (s - perim_dist_seg2) * (s - perim_dist_seg3)));
      result = area;     
   
      return result;
   }


   void Triangle :: display () const
   {
      // Compute the other two corners
      Point p0 (vertex0.get_x (), vertex0.get_y ());
      Point p1 (vertex1.get_x (), vertex1.get_y ());
      Point p2 (vertex2.get_x (), vertex2.get_y ());
   
   	// Compute and display the sides
      Line a (p0,p1), b (p1,p2), c (p2,p0);
      cwin << a << b << c;
   }


   void Triangle :: get (string p)
   {
      p += "  Press <Enter> to continue.";
      string temp = cwin.get_string (p);
   
      Point v0, v1, v2;
   
      v0 = cwin.get_mouse ("Click on the first vertice.");
      v1 = cwin.get_mouse ("Click on the second vertice.");
      v2 = cwin.get_mouse ("Click on the third vertice.");
   
      vertex0 = v0;
      vertex1 = v1;
      vertex2 = v2;
   }

// Function definitions

   void xgio_point_display_coordinates (Point p)
   {
      //Display a pair of messages for the x-coordinate of p       
      double x_coord = p.get_x ();
      Point xm1_start = p; xm1_start.move (1.0, 0.0);
      string xm1_message = "x= ";
      Message xm1 (xm1_start, xm1_message);
      Point xm2_start = xm1_start; xm2_start.move (1.0, 0.0);
      Message xm2 (xm2_start, x_coord);
      cwin << xm1 << xm2;
   
      // Display a pair of messages for the y-coordinate of p     
      double y_coord = p.get_y ();
      Point ym1_start = xm1_start; ym1_start.move (0.0, -1.0);   
      string ym1_message = "y= ";
      Message ym1 (ym1_start, ym1_message);
      Point ym2_start = ym1_start; ym2_start.move (1.0, 0.0);
      Message ym2 (ym2_start, y_coord);
      cwin << ym1 << ym2;
   }

   void xgio_pause ()
   {
      string t = cwin.get_string ("-- Press <Enter> to continue --");
   }
