#include "gfx.h"
#include "ILI9341.h"
#include <math.h>
#include "settings.h"

double ox,oy;
//------------------------------------------------------------------------------
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
//------------------------------------------------------------------------------
void swap(int16_t *xp, int16_t *yp) 
{ 
    int16_t temp = *xp; 
    *xp = *yp; 
    *yp = temp; 
}
//------------------------------------------------------------------------------
// Fill a triangle - original Adafruit function
void GFX_fillTriangle ( int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) 
{

  int16_t a, b, y, last;

  // Sort coordinates by Y order (y2 >= y1 >= y0)
  if (y0 > y1) {
    swap(&y0, &y1); swap(&x0, &x1);
  }
  if (y1 > y2) {
    swap(&y2, &y1); swap(&x2, &x1);
  }
  if (y0 > y1) {
    swap(&y0, &y1); swap(&x0, &x1);
  }

  if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing
    a = b = x0;
    if(x1 < a)      a = x1;
    else if(x1 > b) b = x1;
    if(x2 < a)      a = x2;
    else if(x2 > b) b = x2;
    ILI9341_Hline(color, a, y0, b-a+1);
    return;
  }

  int16_t
    dx01 = x1 - x0,
    dy01 = y1 - y0,
    dx02 = x2 - x0,
    dy02 = y2 - y0,
    dx12 = x2 - x1,
    dy12 = y2 - y1,
    sa   = 0,
    sb   = 0;

  // For upper part of triangle, find scanline crossings for segments
  // 0-1 and 0-2.  If y1=y2 (flat-bottomed triangle), the scanline y1
  // is included here (and second loop will be skipped, avoiding a /0
  // error there), otherwise scanline y1 is skipped here and handled
  // in the second loop...which also avoids a /0 error here if y0=y1
  // (flat-topped triangle).
  if(y1 == y2) last = y1;   // Include y1 scanline
  else         last = y1-1; // Skip it

  for(y=y0; y<=last; y++) {
    a   = x0 + sa / dy01;
    b   = x0 + sb / dy02;
    sa += dx01;
    sb += dx02;

    if(a > b) swap(&a,&b);
    ILI9341_Hline(color, a, y, b-a+1);
  }

  // For lower part of triangle, find scanline crossings for segments
  // 0-2 and 1-2.  This loop is skipped if y1=y2.
  sa = dx12 * (y - y1);
  sb = dx02 * (y - y0);
  for(; y<=y2; y++) {
    a   = x1 + sa / dy12;
    b   = x0 + sb / dy02;
    sa += dx12;
    sb += dx02;

    if(a > b) swap(&a,&b);
    ILI9341_Hline(color, a, y, b-a+1);
  }
}
//------------------------------------------------------------------------------
//int GFX_ringMeter(int value, int vmin, int vmax, int x, int y, int r, uint8_t scheme)
//{
//  // Minimum value of r is about 52 before value text intrudes on ring
//  // drawing the text first is an option
//  // https://www.instructables.com/id/Arduino-analogue-ring-meter-on-colour-TFT-display/
//  //https://www.instructables.com/member/Bodmer/
//  
//    uint8_t str[10];
//  x += r; y += r;   // Calculate coords of centre of ring
//
//  int w = r / 4;    // Width of outer ring is 1/4 of radius
//  
//  int angle = 150;  // Half the sweep angle of meter (300 degrees)
//
//  int text_colour = 0; // To hold the text colour
//
//  int v = map(value, vmin, vmax, -angle, angle); // Map the value to an angle v
//
//  uint8_t seg = 5; // Segments are 5 degrees wide = 60 segments for 300 degrees
//  uint8_t inc = 5; // Draw segments every 5 degrees, increase to 10 for segmented ring
//  int i;
//
//  // Draw colour blocks every inc degrees
//  for (i = -angle; i < angle; i += inc) {
//
//    // Choose colour from scheme
//    int colour = 0;
//    switch (scheme) {
//      case 0: colour = RED; break; // Fixed colour
//      case 1: colour = GREEN; break; // Fixed colour
//      case 2: colour = BLUE; break; // Fixed colour
//      case 3: colour = rainbow(map(i, -angle, angle, 0, 127)); break; // Full spectrum blue to red
//      case 4: colour = rainbow(map(i, -angle, angle, 63, 127)); break; // Green to red (high temperature etc)
//      case 5: colour = rainbow(map(i, -angle, angle, 127, 63)); break; // Red to green (low battery etc)
//      default: colour = BLUE; break; // Fixed colour
//    }
//
//    // Calculate pair of coordinates for segment start
//    float sx = cosf((i - 90) * 0.0174532925);
//    float sy = sinf((i - 90) * 0.0174532925);
//    uint16_t x0 = sx * (r - w) + x;
//    uint16_t y0 = sy * (r - w) + y;
//    uint16_t x1 = sx * r + x;
//    uint16_t y1 = sy * r + y;
//
//    // Calculate pair of coordinates for segment end
//    float sx2 = cosf((i + seg - 90) * 0.0174532925);
//    float sy2 = sinf((i + seg - 90) * 0.0174532925);
//    int x2 = sx2 * (r - w) + x;
//    int y2 = sy2 * (r - w) + y;
//    int x3 = sx2 * r + x;
//    int y3 = sy2 * r + y;
//
//    if (i < v) { // Fill in coloured segments with 2 triangles
//      GFX_fillTriangle(x0, y0, x1, y1, x2, y2, colour);
//      GFX_fillTriangle(x1, y1, x2, y2, x3, y3, colour);
//      text_colour = colour; // Save the last colour drawn
//    }
//    else // Fill in blank segments
//    {
//      GFX_fillTriangle(x0, y0, x1, y1, x2, y2, LIGHTGREY);
//      GFX_fillTriangle(x1, y1, x2, y2, x3, y3, LIGHTGREY);
//    }
//  }
//  
//  
//
//  // Calculate and return right hand side x coordinate
//  return x + r;
//}
//------------------------------------------------------------------------------
unsigned int rainbow(uint8_t value)
{
  // Value is expected to be in range 0-127
  // The value is converted to a spectrum colour from 0 = blue through to 127 = red

  uint8_t red = 0; // Red is the top 5 bits of a 16 bit colour value
  uint8_t green = 0;// Green is the middle 6 bits
  uint8_t blue = 0; // Blue is the bottom 5 bits

  uint8_t quadrant = value / 32;

  if (quadrant == 0) {
    blue = 31;
    green = 2 * (value % 32);
    red = 0;
  }
  if (quadrant == 1) {
    blue = 31 - (value % 32);
    green = 63;
    red = 0;
  }
  if (quadrant == 2) {
    blue = 0;
    green = 63;
    red = value % 32;
  }
  if (quadrant == 3) {
    blue = 0;
    green = 63 - 2 * (value % 32);
    red = 31;
  }
  return (red << 11) + (green << 5) + blue;
}
//------------------------------------------------------------------------------
void GFX_fillCircle(int16_t x0, int16_t y0, int16_t r,
			      uint16_t color) {
  ILI9341_Vline(color, x0, y0-r, 2*r+1);
  fillCircleHelper(x0, y0, r, 3, 0, color);
}

// Used to do circles and roundrects
void fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
    uint8_t cornername, int16_t delta, uint16_t color) {

  int16_t f     = 1 - r;
  int16_t ddF_x = 1;
  int16_t ddF_y = -2 * r;
  int16_t x     = 0;
  int16_t y     = r;

  while (x<y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f     += ddF_y;
    }
    x++;
    ddF_x += 2;
    f     += ddF_x;

    if (cornername & 0x1) {
      ILI9341_Vline(color, x0+x, y0-y, 2*y+1+delta);
      ILI9341_Vline(color, x0+y, y0-x, 2*x+1+delta);
    }
    if (cornername & 0x2) {
      ILI9341_Vline(color, x0-x, y0-y, 2*y+1+delta);
      ILI9341_Vline(color, x0-y, y0-x, 2*x+1+delta);
    }
  }
}
//------------------------------------------------------------------------------
// Draw a triangle
void GFX_drawTriangle(int16_t x0, int16_t y0,
				int16_t x1, int16_t y1,
				int16_t x2, int16_t y2, uint16_t color) {
  ILI9341_line(color, x0, y0, x1, y1);
  ILI9341_line(color, x1, y1, x2, y2);
  ILI9341_line(color, x2, y2, x0, y0);
}
//------------------------------------------------------------------------------
// Draw a circle outline
void GFX_drawCircle(int16_t x0, int16_t y0, int16_t r,
    uint16_t color) {
  int16_t f = 1 - r;
  int16_t ddF_x = 1;
  int16_t ddF_y = -2 * r;
  int16_t x = 0;
  int16_t y = r;

  ILI9341_pixel(color, x0  , y0+r);
  ILI9341_pixel(color, x0  , y0-r);
  ILI9341_pixel(color, x0+r, y0  );
  ILI9341_pixel(color, x0-r, y0  );

  while (x<y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;
  
    ILI9341_pixel(color, x0 + x, y0 + y);
    ILI9341_pixel(color, x0 - x, y0 + y);
    ILI9341_pixel(color, x0 + x, y0 - y);
    ILI9341_pixel(color, x0 - x, y0 - y);
    ILI9341_pixel(color, x0 + y, y0 + x);
    ILI9341_pixel(color, x0 - y, y0 + x);
    ILI9341_pixel(color, x0 + y, y0 - x);
    ILI9341_pixel(color, x0 - y, y0 - x);
  }
}

void drawCircleHelper( int16_t x0, int16_t y0,
               int16_t r, uint8_t cornername, uint16_t color) {
  int16_t f     = 1 - r;
  int16_t ddF_x = 1;
  int16_t ddF_y = -2 * r;
  int16_t x     = 0;
  int16_t y     = r;

  while (x<y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f     += ddF_y;
    }
    x++;
    ddF_x += 2;
    f     += ddF_x;
    if (cornername & 0x4) {
      ILI9341_pixel(color, x0 + x, y0 + y);
      ILI9341_pixel(color, x0 + y, y0 + x);
    } 
    if (cornername & 0x2) {
      ILI9341_pixel(color, x0 + x, y0 - y);
      ILI9341_pixel(color, x0 + y, y0 - x);
    }
    if (cornername & 0x8) {
      ILI9341_pixel(color, x0 - y, y0 + x);
      ILI9341_pixel(color, x0 - x, y0 + y);
    }
    if (cornername & 0x1) {
      ILI9341_pixel(color, x0 - y, y0 - x);
      ILI9341_pixel(color, x0 - x, y0 - y);
    }
  }
}

////------------------------------------------------------------------------------
///*
//  function to draw a cartesian coordinate system and plot whatever data you want
//  just pass x and y and the graph will be drawn
//  huge arguement list
//  &d name of your display object
//  x = x data point
//  y = y datapont
//  gx = x graph location (lower left)
//  gy = y graph location (lower left)
//  w = width of graph
//  h = height of graph
//  xlo = lower bound of x axis
//  xhi = upper bound of x asis
//  xinc = division of x axis (distance not count)
//  ylo = lower bound of y axis
//  yhi = upper bound of y asis
//  yinc = division of y axis (distance not count)
//  title = title of graph
//  xlabel = x asis label
//  ylabel = y asis label
//  gcolor = graph line colors
//  acolor = axi ine colors
//  pcolor = color of your plotted data
//  tcolor = text color
//  bcolor = background color
//  &redraw = flag to redraw graph on fist call only
//*/
//void GFX_Graph(double x, double y, double gx, double gy, double w, double h, double xlo, double xhi, double xinc, double ylo, double yhi, double yinc, uint8_t title[], uint8_t xlabel[], uint8_t ylabel[], unsigned int gcolor, unsigned int acolor, unsigned int pcolor, unsigned int tcolor, unsigned int bcolor, uint8_t redraw) 
//{
//  //AUTOR: Kris Kasprzak
//  double ydiv, xdiv;
//  // initialize old x and old y in order to draw the first point of the graph
//  // but save the transformed value
//  // note my transform funcition is the same as the map function, except the map uses long and we need doubles
////  double ox = (x - xlo) * ( w) / (xhi - xlo) + gx;
////  double oy = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
//  double i;
//  double temp;
//  int rot, newrot;
//
//  if (redraw == 1) {
//
//    redraw = 0;
//    ox = (x - xlo) * ( w) / (xhi - xlo) + gx;
//    oy = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
//    // draw y scale
//    for ( i = ylo; i <= yhi; i += yinc) {
//      // compute the transform
//      temp =  (i - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
//
//      if (i == 0) {
//        ILI9341_line(acolor, gx, temp, gx + w, temp);
//      }
//      else {
//        ILI9341_line(gcolor, gx, temp, gx + w, temp);
//      }
//
////      ILI9341_string()
////      d.setTextSize(1);
////      d.setTextColor(tcolor, bcolor);
////      d.setCursor(gx - 40, temp);
////      // precision is default Arduino--this could really use some format control
////      d.println(i);
//    }
//    // draw x scale
//    for (i = xlo; i <= xhi; i += xinc) {
//
//      // compute the transform
//
//      temp =  (i - xlo) * ( w) / (xhi - xlo) + gx;
//      if (i == 0) {
//        ILI9341_line(acolor, temp, gy, temp, gy - h);
//      }
//      else {
//        ILI9341_line(gcolor, temp, gy, temp, gy - h);
//      }
//
////      d.setTextSize(1);
////      d.setTextColor(tcolor, bcolor);
////      d.setCursor(temp, gy + 10);
////      // precision is default Arduino--this could really use some format control
////      d.println(i);
//    }
//
//    ILI9341_string(title,gx,gy - h - 30,tcolor,bcolor,droidSansMono_8ptBitmaps,droidSansMono_8ptDescriptors);
////    //now draw the labels
////    d.setTextSize(2);
////    d.setTextColor(tcolor, bcolor);
////    d.setCursor(gx , gy - h - 30);
////    d.println(title);
//    ILI9341_string(xlabel,gx,gy + 20,acolor,bcolor,droidSansMono_8ptBitmaps,droidSansMono_8ptDescriptors);
////    d.setTextSize(1);
////    d.setTextColor(acolor, bcolor);
////    d.setCursor(gx , gy + 20);
////    d.println(xlabel);
//    ILI9341_string(ylabel,gx-30,gy - h - 10,acolor,bcolor,droidSansMono_8ptBitmaps,droidSansMono_8ptDescriptors);
////    d.setTextSize(1);
////    d.setTextColor(acolor, bcolor);
////    d.setCursor(gx - 30, gy - h - 10);
////    d.println(ylabel);
//
//
//  }
//
//  //graph drawn now plot the data
//  // the entire plotting code are these few lines...
//  // recall that ox and oy are initialized as static above
//  x =  (x - xlo) * ( w) / (xhi - xlo) + gx;
//  y =  (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
//  ILI9341_line(pcolor, ox, oy, x, y);
//  ILI9341_line(pcolor, ox, oy + 1, x, y + 1);
//  ILI9341_line(pcolor, ox, oy - 1, x, y - 1);
//  ox = x;
//  oy = y;
//
//}


////------------------------------------------------------------------------------
///*
//  This method will draw a dial-type graph for single input
//  it has a rather large arguement list and is as follows
//  &d = display object name
//  cx = center position of dial
//  cy = center position of dial
//  r = radius of the dial
//  loval = lower value of the scale (can be negative)
//  hival = upper value of the scale
//  inc = scale division between loval and hival
//  sa = sweep angle for the dials scale
//  curval = date to graph (must be between loval and hival)
//  dig = format control to set number of digits to display (not includeing the decimal)
//  dec = format control to set number of decimals to display (not includeing the decimal)
//  needlecolor = color of the needle
//  dialcolor = color of the dial
//  textcolor = color of all text (background is dialcolor)
//  label = bottom lable text for the graph
//  redraw = flag to redraw display only on first pass (to reduce flickering)
//*/
//void DrawDial(int cx, int cy, int r, double loval , double hival , double inc, double sa, double curval,  int dig , int dec, unsigned int needlecolor, unsigned int dialcolor, unsigned int  textcolor, uint8_t label[], uint8_t redraw) {
//
//  double ix, iy, ox, oy, tx, ty, lx, rx, ly, ry, i, offset, stepval, data, angle;
//  double degtorad = .0174532778;
//  double px = cx, py = cy, pix = cx, piy = cy, plx = cx, ply = cy, prx = cx, pry = cy;
//
//  // draw the dial only one time--this will minimize flicker
//  if ( redraw == 1) {
//    redraw = 0;
//    GFX_fillCircle(cx, cy, r - 2, dialcolor);
//    GFX_drawCircle(cx, cy, r, needlecolor);
//    GFX_drawCircle(cx, cy, r - 1, needlecolor);
////    d.setTextColor(textcolor, dialcolor);
////    d.setTextSize(2);
////    d.setCursor(cx - 25, cy + 40);
////    d.println(label);
//
//  }
//  // draw the current value
////  d.setTextSize(2);
////  d.setTextColor(textcolor, dialcolor);
////  d.setCursor(cx - 25, cy + 20 );
////  d.println(Format(curval, dig, dec));
//  // center the scale about the vertical axis--and use this to offset the needle, and scale text
//  offset = (270 +  sa / 2) * degtorad;
//  // find hte scale step value based on the hival low val and the scale sweep angle
//  // deducting a small value to eliminate round off errors
//  // this val may need to be adjusted
//  stepval = ( inc) * (double) (sa) / (double) (hival - loval) + .00;
//  // draw the scale and numbers
//  // note draw this each time to repaint where the needle was
//  for (i = 0; i <= sa; i += stepval) {
//    angle = ( i  * degtorad);
//    angle = offset - angle ;
//    ox =  (r - 2) * cos(angle) + cx;
//    oy =  (r - 2) * sin(angle) + cy;
//    ix =  (r - 10) * cos(angle) + cx;
//    iy =  (r - 10) * sin(angle) + cy;
//    tx =  (r - 30) * cos(angle) + cx;
//    ty =  (r - 30) * sin(angle) + cy;
//    ILI9341_line(textcolor, ox, oy, ix, iy);
////    d.setTextSize(1.5);
////    d.setTextColor(textcolor, dialcolor);
////    d.setCursor(tx - 10, ty );
//    data = hival - ( i * (inc / stepval)) ;
////    d.println(Format(data, dig, dec));
//  }
//  // compute and draw the needle
//  angle = (sa * (1 - (((curval - loval) / (hival - loval)))));
//  angle = angle * degtorad;
//  angle = offset - angle  ;
//  ix =  (r - 10) * cos(angle) + cx;
//  iy =  (r - 10) * sin(angle) + cy;
//  // draw a triangle for the needle (compute and store 3 vertiticies)
//  lx =  5 * cos(angle - 90 * degtorad) + cx;
//  ly =  5 * sin(angle - 90 * degtorad) + cy;
//  rx =  5 * cos(angle + 90 * degtorad) + cx;
//  ry =  5 * sin(angle + 90 * degtorad) + cy;
//  // first draw the previous needle in dial color to hide it
//  // note draw performance for triangle is pretty bad...
//
//  //GFX_fillTriangle (pix, piy, plx, ply, prx, pry, dialcolor);
//  //GFX_fillTriangle (pix, piy, plx, ply, prx, pry, dialcolor);
//
//  //GFX_fillTriangle (pix, piy, plx, ply, prx - 20, pry - 20, dialcolor);
//  //GFX_fillTriangle (pix, piy, prx, pry, prx + 20, pry + 20, dialcolor);
//
//  GFX_fillTriangle (pix, piy, plx, ply, prx, pry, dialcolor);
//  GFX_drawTriangle (pix, piy, plx, ply, prx, pry, dialcolor);
//
//  // then draw the old needle in need color to display it
//  GFX_fillTriangle (ix, iy, lx, ly, rx, ry, needlecolor);
//  GFX_drawTriangle (ix, iy, lx, ly, rx, ry, textcolor);
//
//  // draw a cute little dial center
//  GFX_fillCircle(cx, cy, 8, textcolor);
//  //save all current to old so the previous dial can be hidden
//  pix = ix;
//  piy = iy;
//  plx = lx;
//  ply = ly;
//  prx = rx;
//  pry = ry;
//
//}

//------------------------------------------------------------------------------
//vlastny graf
//redraw = 0 - nakresli novy graf
//redraw = 1 - len data
//redraw = 2 - vymaze data a nakresli hodnoty na osach
//hodnota x sa zadava len v rozsahu sirky grafu, nie hodnoty xmax - ta sluzi len na oznacenie x-ovej osi
void GFX_graf(uint32_t x, uint32_t y, uint32_t xmax, uint32_t ymax, uint32_t ymin, uint8_t xdiv, uint8_t ydiv, uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint8_t xlabel[], uint8_t ylabel[], uint8_t redraw, uint16_t color)
{
    
    volatile uint16_t temp, ypos_temp, temp2, temp3, ye;
    volatile uint16_t i,j,k,m;
    //hodnoty os na jeden dielik (xdiv a ydiv)
    volatile uint16_t xvalue;
    volatile uint16_t yvalue;
    volatile uint8_t buffer[10];
    float xfrac,yfrac;
    static uint16_t xold, yold, first;
    ypos_temp = 319-ypos;
    ye = ypos_temp-1;
    
    if(redraw==0||redraw==2)
    {
        temp = width/xdiv;
        temp2 = height/ydiv;
        //ILI9341_fillrect(ILI9341_WHITE,xpos+1,ypos_temp-height-1,xpos+width+1,ye);
        k=0;
        m=0;
        for(i=0;i<ydiv;i++)
        {
            for(j=0;j<xdiv;j++)
            {
                if(j==xdiv-1)
                    m=1;
                else
                    m=0;
                ILI9341_fillrect(BLACK,xpos+1+(j*temp),ypos_temp-height+(i*temp2)+k,xpos+(j*temp)+temp-1+m,ypos_temp-height+(i*temp2)+temp2-1);
            }
            k = 1;
        }
        if(redraw==0)
        {
            ILI9341_Hline(WHITE,xpos,ypos_temp,width);
            ILI9341_Vline(WHITE,xpos,ypos_temp-height,height);
        }
        
        first = 0;
        
        if(xdiv!=0)
        {
            temp = width/xdiv;
            xvalue = xmax/xdiv;
            for(i=0;i<xdiv;i++)
            {
                ILI9341_Vline(LIGHTGREY,(xpos+(i*temp)),(ypos_temp-(height)),height-1);
                temp2 = i*xvalue;
                int2str(temp2,buffer);
                temp3 = 4;
                if(temp2<1000)
                    temp3 = 5;
                if(temp2<100)
                    temp3 = 6;
                if(temp2<10)
                    temp3 = 7;
                if(redraw==0)
                    ILI9341_center_string(&buffer[temp3],(xpos+(i*temp)),(ypos_temp+8),WHITE,BLACK,droidSansMono_8ptBitmaps, droidSansMono_8ptDescriptors);
            }
            ILI9341_center_string(xlabel,(xpos+(xdiv*temp)),(ypos_temp+8),WHITE,BLACK,droidSansMono_8ptBitmaps, droidSansMono_8ptDescriptors);
        }
        if(ydiv!=0)
        {
            yvalue=(ymax-ymin)/ydiv;
            temp = height/ydiv;
            for(i=0;i<ydiv;i++)
            {
                ILI9341_Hline(LIGHTGREY,xpos+1,(ypos_temp-(i*temp)),width-1);
                temp2 = (i*yvalue)+ymin;
                int2str(temp2,buffer);
                temp3 = 3;
                if(temp2<10000)
                    temp3 = 4;
                if(temp2<1000)
                    temp3 = 5;
                if(temp2<100)
                    temp3 = 6;
                if(temp2<10)
                    temp3 = 7;
                if(redraw==0)
                {
                    ILI9341_center_string("     ",(xpos-20),(ypos_temp-(i*temp)),WHITE,BLACK,droidSansMono_8ptBitmaps, droidSansMono_8ptDescriptors);
                    ILI9341_center_string(&buffer[temp3],(xpos-20),(ypos_temp-(i*temp)),WHITE,BLACK,droidSansMono_8ptBitmaps, droidSansMono_8ptDescriptors);
                }
            }
            ILI9341_center_string(ylabel,(xpos-14),(ypos_temp-(ydiv*temp)),WHITE,BLACK,droidSansMono_8ptBitmaps, droidSansMono_8ptDescriptors);
        }
    }
    
    Nop();
    if(y>ymax)
        y = ymax;
    if(y<ymin)
        y = ymin;
    yfrac = (((float)y-ymin)/(ymax-ymin))*height;
    Nop();
    //kreslenie grafu
    if(first==0)
    {
        if((x<width)&&((uint16_t)yfrac<=height))
            ILI9341_line(color, x+xpos+1, ypos_temp-(uint16_t)yfrac, x+xpos+1, ypos_temp-(uint16_t)yfrac);
    }
    else
    {
        if((x>xold)&&(x<width)&&((uint16_t)yfrac<=height))
            ILI9341_line(color, xold+xpos+1, ypos_temp-yold, x+xpos+1, ypos_temp-(uint16_t)yfrac);
    }
    xold = x;
    yold = (uint16_t)yfrac;
    first = 1;
}