/*-----------------------------------------------------------------------------
//     $Date: 2004/08/30 21:15:08 $
//     $RCSfile: bootload_basicgraphics.c,v $
//-----------------------------------------------------------------------------
//
//     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
//     SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR
//     XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION
//     AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION
//     OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS
//     IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
//     AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
//     FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
//     WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
//     IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
//     REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
//     INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//     FOR A PARTICULAR PURPOSE.
//     
//     (c) Copyright 2004 Xilinx, Inc.
//     All rights reserved.
//
//---------------------------------------------------------------------------*/

#include "xio.h"
#include "xtft.h"
#include "sleep.h"
#include "math.h"
#include "bootload_basicgraphics.h"

#define DISPLAY_COLUMNS  640
#define DISPLAY_ROWS     480
#define NORM_FACTOR      1000000

/* values generated by touchcalibrate */
#define DEFAULT_XMULT    956
#define DEFAULT_YMULT    1192
#define DEFAULT_XLCORN   254057
#define DEFAULT_YLCORN   197499

/*   GLOBALS    */
int Xpixel, Ypixel, Xmult, Ymult, Xlcorn, Ylcorn;

#define TFT_WIDTH        640
#define CHAR_WIDTH       8
#define CHAR_HEIGHT      12

/* XTft_WriteString: Writes a string of characters to the TFT */
void XTft_WriteString(XTft *InstancePtr, unsigned char *val) 
{
  while (*val) {
    XTft_Write(InstancePtr, *val);
    val++;
  }
}

/* XTft_WriteColor: Writes a character with a specified colour */
void XTft_WriteColor(XTft *InstancePtr, unsigned char c, 
		     unsigned int fgCol, unsigned int bgCol) 
{
  XTft_SetColor(InstancePtr, fgCol, bgCol);
  XTft_Write(InstancePtr, (Xint8)c);
}

/* XTft_WriteColorString: Writes a string with a specified colour */
void XTft_WriteColorString(XTft *InstancePtr, 
			   unsigned char *val, unsigned int fgCol, unsigned int bgCol)
{
  while (*val) {
    XTft_WriteColor(InstancePtr, *val, fgCol, bgCol);
    val++;
  }
}

/* XTft_WriteColorCenteredString: Writes a string with a specified color, 
 * centered along a specified column                                      */
void XTft_WriteColorCenteredString(XTft *InstancePtr, 
				   char * str, unsigned fgCol, unsigned int bgCol, int ypos)
{
	int totalWidth = strlen(str) * CHAR_WIDTH;

	XTft_SetPos(InstancePtr, TFT_WIDTH/2 - totalWidth/2, ypos);
	XTft_WriteColorString(InstancePtr, str, fgCol, bgCol);
}

/* XTft_WriteCenteredString: Writes a string centered along a specified column */
void XTft_WriteCenteredString(XTft *InstancePtr, char * str, int ypos)
{
	int totalWidth = strlen(str) * CHAR_WIDTH;

	XTft_SetPos(InstancePtr, TFT_WIDTH / 2 - totalWidth / 2, ypos);
	XTft_WriteString(InstancePtr, str);
}

/* XTft_DrawPixel: Draws a pixel with the specified colour 
 * at a specified location                                 */
int XTft_DrawPixel(XTft *InstancePtr, int x, int y, unsigned int col)
{
   if (x >= 0 &&
       x <= DISPLAY_COLUMNS-1 &&
       y >= 0 &&
       y <= DISPLAY_ROWS-1) {
     XTft_SetPixel(InstancePtr, x, y, col);
     return 0;
   }
   else {
     return 1;
   }
}

/* XTft_DrawLine: Draws a line between two points with
 * with a specified color                              */
int XTft_DrawLine(XTft *InstancePtr,
		  int x1, int y1, int x2, int y2, unsigned int col)
{
  
  int slope, yintercept;
  int xmin, ymin, xmax, ymax, i, j, mx;
  
  if (x1 >= 0 &&
      x1 <= DISPLAY_COLUMNS-1 &&
      x2 >= 0 &&
      x2 <= DISPLAY_COLUMNS-1 &&
      y1 >= 0 &&
      y1 <= DISPLAY_ROWS-1 &&
      y2 >= 0 &&
      y2 <= DISPLAY_ROWS-1) {
    
    if (x2-x1 != 0) {
      slope = ((y2-y1)/(x2-x1)*100000);     /* Calculate slope */
      yintercept = y1-((slope/100000)*x1);  /* Calculate yintercept */
    }
    else { /* divide by zero */
      slope = 0;
      yintercept = (-1);
    }
    
    if (x2 < x1) {
      xmin = x2;
      xmax = x1;
    }
    else {
      xmin = x1;
      xmax = x2;
    }
    if (y2 < y1) {
      ymin = y2;
      ymax = y1;
    }
    else {
      ymin = y1;
      ymax = y2;
    }

    for (i=xmin; i<=xmax; i++) {
      mx = (slope * i) / 100000;
      for (j=ymin; j<=ymax; j++) {
	if ((j - mx) == yintercept) { /* Calculate visible line */
	  XTft_SetPixel(InstancePtr, i, j, col);
	}
	else {
	  if ((slope == 0) && (yintercept == -1)) { /* divide by zero */
	    XTft_SetPixel(InstancePtr, i, j, col);  /* a.k.a vertical line */
	  }
	}
      }
    }
    return 0;
  }
  else {
    return 1;
  }
}

/* XTft_DrawEmptyBox:  Draws a box on the TFT of a specified
 * color between two points, with a given thickness          */
int XTft_DrawEmptyBox(XTft *InstancePtr,
		      int x1, int y1, int x2, int y2, unsigned int col, int thickness)
{
   int xmin, xmax, ymin, ymax, i;

   if (x1 >= 0 &&
       x1 <= DISPLAY_COLUMNS-1 &&
       x2 >= 0 &&
       x2 <= DISPLAY_COLUMNS-1 &&
       y1 >= 0 &&
       y1 <= DISPLAY_ROWS-1 &&
       y2 >= 0 &&
       y2 <= DISPLAY_ROWS-1) {
      if (x2 < x1) {
	xmin = x2;
	xmax = x1;
      }
      else {
	xmin = x1;
	xmax = x2;
      }
      if (y2 < y1) {
	ymin = y2;
	ymax = y1;
      }
      else {
	ymin = y1;
	ymax = y2;
      }

      for (i = 0;i < thickness;i++) {
        XTft_DrawLine(InstancePtr, xmin+i, ymin+i, xmax+i, ymin+i, col);
        XTft_DrawLine(InstancePtr, xmin+i, ymin+i, xmin+i, ymax+i, col);
        XTft_DrawLine(InstancePtr, xmax+i, ymax+i, xmax+i, ymin+i, col);
        XTft_DrawLine(InstancePtr, xmin+i, ymax+i, xmax+i, ymax+i, col);
      }
   }

   return 0;
}


/* XTft_DrawSolidBox:  Draws a box on the TFT of a specified
 * color between two points                                  */
int XTft_DrawSolidBox(XTft *InstancePtr, int x1, int y1, int x2, int y2, unsigned int col)
{
   int xmin,xmax,ymin,ymax,i,j;

   if (x1 >= 0 &&
       x1 <= DISPLAY_COLUMNS-1 &&
       x2 >= 0 &&
       x2 <= DISPLAY_COLUMNS-1 &&
       y1 >= 0 &&
       y1 <= DISPLAY_ROWS-1 &&
       y2 >= 0 &&
       y2 <= DISPLAY_ROWS-1) {
      if (x2 < x1) {
         xmin = x2;
         xmax = x1;
      }
      else {
         xmin = x1;
         xmax = x2;
      }
      if (y2 < y1) {
         ymin = y2;
         ymax = y1;
      }
      else {
         ymin = y1;
         ymax = y2;
      }

      for (i=xmin; i<=xmax; i++) {
         for (j=ymin; j<=ymax; j++) {
	   XTft_SetPixel(InstancePtr, i, j, col);
         }
      }
      return 0;
   }
   return 1;

}


