/* section.C
 */


#include <math.h>
#include "section.h"
#include "xy.h"
#include "main.h"

#ifdef GL
  #include <GL/gl.h>
#endif


int Section::nextIdent = 0;


/* Upon entering a section, (x0,y0) and (x1,y1) are swapped if
 * necessary so that the train is travelling FROM (x0,y0) TO (x1,y1).
 * Also, adjMain[0] and adjBranch[0] are made the main and branch
 * section FROM WHICH THE TRAIN CAME and adjMain[1] and adjBranch[1]
 * are made those TOWARD WHICH THE TRAIN IS TRAVELLING.
 */


void
Section::reverseSection()

{
  float tempFloat;
  Section *tempSection;

  if (trainPresent) {
    cerr << "Internal Error: trying to reverse a track section, " << *this
	 << ", which is currently occupied.\n";
    abort();
  }

  tempFloat = x0; x0 = x1; x1 = tempFloat;
  tempFloat = y0; y0 = y1; y1 = tempFloat;
  tempSection = adjMain[0]; adjMain[0] = adjMain[1]; adjMain[1] = tempSection;
  tempSection = adjBranch[0]; adjBranch[0] = adjBranch[1]; adjBranch[1] = tempSection;

  reversed = !reversed;
}


void
Section::reverseOccupiedSection()

{
  float tempFloat;
  Section *tempSection;

  tempFloat = x0; x0 = x1; x1 = tempFloat;
  tempFloat = y0; y0 = y1; y1 = tempFloat;
  tempSection = adjMain[0]; adjMain[0] = adjMain[1]; adjMain[1] = tempSection;
  tempSection = adjBranch[0]; adjBranch[0] = adjBranch[1]; adjBranch[1] = tempSection;

  reversed = !reversed;
}


/* draw the section as a single line
 */


#define ZIGZAG_HALFWIDTH  5	// for drawing /\/\/\/\ on locked sections
#define ZIGZAG_LENGTH     10

void
Section::draw()

{
#ifdef GL
  static bool drawFrozenAsZigzag = true;
  static float lastAlternationTime = -1;

  float dx = x1-x0;
  float dy = y1-y0;
  float len = sqrt(dx*dx+dy*dy);
  dx /= len;
  dy /= len;
  
  switch (stat) {
  case RED:    glColor3f( 0.9, 0.1, 0.1 ); break;
  case YELLOW: glColor3f( 0.8, 0.8, 0.1 ); break;
  case GREEN:  glColor3f( 0.1, 0.9, 0.1 ); break;
  }

  glLineWidth( 1 );

  // Draw frozen sections alternately as straight segments and
  // zigzags.  Alternate the drawing method with every redraw.

  if (currentTime != lastAlternationTime) {
    drawFrozenAsZigzag = !drawFrozenAsZigzag;
    lastAlternationTime = currentTime;
  }

  // Draw the section

  if (! frozenStatus  ||  !drawFrozenAsZigzag ) { // draw straight segment

    glBegin( GL_LINES );
    glVertex2f( x0, y0 );
    glVertex2f( x1, y1 );
    glEnd();

  } else {			// draw zigzag 

    float numZigzags   = ceil( len / (float) ZIGZAG_LENGTH );
    float zigzagLength = len / numZigzags;
    float lastX = x0;
    float lastY = y0;

    glBegin( GL_LINE_STRIP );
    glVertex2f( lastX, lastY );

    for (int i=0; i<(int)numZigzags; i++) {
      glVertex2f( lastX + 0.25*zigzagLength*dx + ZIGZAG_HALFWIDTH*(-dy), 
		  lastY + 0.25*zigzagLength*dy + ZIGZAG_HALFWIDTH*dx );
      glVertex2f( lastX + 0.75*zigzagLength*dx - ZIGZAG_HALFWIDTH*(-dy), 
		  lastY + 0.75*zigzagLength*dy - ZIGZAG_HALFWIDTH*dx );
      lastX = lastX + zigzagLength*dx;
      lastY = lastY + zigzagLength*dy;
      glVertex2f( lastX, lastY );
    }
    
    glEnd();
  }

  if (showSectionDirections) {	// arrowhead to show current section direction (for debugging)
    glBegin( GL_LINES );
    glVertex2f( x1, y1 );
    glVertex2f( x1 - 15*dx - 5*dy, y1 - 15*dy + 5*dx );
    glVertex2f( x1, y1 );
    glVertex2f( x1 - 15*dx + 5*dy, y1 - 15*dy - 5*dx );
    glEnd();
  }

  glPointSize(2);

  glColor3f(0,0,0);

  glBegin( GL_POINTS );
  glVertex2f( x0, y0 );
  glVertex2f( x1, y1 );
  glEnd();

  glLineWidth( 1 );
#endif
}

