//------------------------------------------------------------------
// qfixLCD.h
//
// This file contains the class LCD which represents the
// LCD display.
//
// Copyright 2004 by KTB mechatronics GmbH
// Author: Stefan Enderle
//------------------------------------------------------------------

#ifndef qfixLCD_h
#define qfixLCD_h


#include "qfixI2C.h"
#include "qfixI2CDefs.h"
#include "string.h"


static const uint8_t LCD_CMD_CHANGEID   = 0;
static const uint8_t LCD_CMD_CLEAR      = 1;
static const uint8_t LCD_CMD_PRINTSTR   = 2;
static const uint8_t LCD_CMD_PRINTSTRXY = 3;
static const uint8_t LCD_CMD_LIGHTON    = 4;
static const uint8_t LCD_CMD_LIGHTOFF   = 5;
static const uint8_t LCD_CMD_PRINTINT   = 6;
static const uint8_t LCD_CMD_PRINTINTXY = 7;



/**
* \class LCD
* \brief Represents the qfix LC-display.
* \author Stefan Enderle
*
* The class LCD represents the
* physical LC-display and can be used to output text.
* The I2C bus is completely abstracted.
*/
class LCD
{
private:
  I2C i2c;
  uint8_t id;

public:
  /** Default constructor. If only one LC-display is used,
  * this constructor can be used. It sets the internal ID to 0.
  */
  LCD();

  /** Constructor with given ID.
  * If two or more LC-displays are used,
  * this constructor must be used. It sets the internal ID to the given value.
  */
  LCD(uint8_t ID);

  /** Change logical device ID
  */
  void changeID(uint8_t newID);

  /** Clears the display
  */
  void clear();

  /** prints the string data at the current cursor position.
   *  The string must end with 0.
  */
  void print(char* data);

  /** Prints the string data at position line/col. The string
   * must end with 0.
  */
  void print(uint8_t line, uint8_t col, char* data);

  /** prints the integer data at the current cursor position.
  */
  void print(int data);

  /** Prints the integer data at position line/col. 
  */
  void print(uint8_t line, uint8_t col, int data);

  /** Puts on the backlight. 
  * \see lightOff
  */
  void lightOn();

  /** Puts off the backlight. 
  * \see lightOff
  */
  void lightOff();
};



LCD::LCD() : i2c(), id(0)
{
}


LCD::LCD(uint8_t ID) : i2c(), id(ID)
{
}


void LCD::clear()
{
  uint8_t buf[2];

  buf[0] = id;
  buf[1] = LCD_CMD_CLEAR;
  i2c.send(I2C_ADDR_LCD, buf, 2);
}


void LCD::print(char* data)
{
  int len=strlen(data);
  uint8_t buf[len+2];

  buf[0] = id;
  buf[1] = LCD_CMD_PRINTSTR;
  for (int i=0; i<len; i++) buf[i+2] = uint8_t(data[i]);

  i2c.send(I2C_ADDR_LCD, buf, len+2);
}


void LCD::print(uint8_t line, uint8_t col, char* data)
{
  int len=strlen(data);
  uint8_t buf[len+4];

  buf[0] = id;
  buf[1] = LCD_CMD_PRINTSTRXY;
  buf[2] = line;
  buf[3] = col;
  for (int i=0; i<len; i++) buf[i+4] = uint8_t(data[i]);

  i2c.send(I2C_ADDR_LCD, buf, len+4);
}


void LCD::print(int data)
{
  int len=sizeof(int);
  uint8_t buf[len+2];
  uint8_t* ptr = (uint8_t*) &data;    // pointer to data

  buf[0] = id;
  buf[1] = LCD_CMD_PRINTINT;
  for (int i=0; i<len; i++) {
    buf[i+2] = *ptr;
    ptr++;
  }

  i2c.send(I2C_ADDR_LCD, buf, len+2);
}


void LCD::print(uint8_t line, uint8_t col, int data)
{
  int len=sizeof(int);
  uint8_t buf[len+4];
  uint8_t* ptr = (uint8_t*) &data;    // pointer to data

  buf[0] = id;
  buf[1] = LCD_CMD_PRINTINTXY;
  buf[2] = line;
  buf[3] = col;
  for (int i=0; i<len; i++) {
    buf[i+4] = *ptr;
    ptr++;
  }

  i2c.send(I2C_ADDR_LCD, buf, len+4);
}


void LCD::lightOn()
{
  uint8_t buf[2];

  buf[0] = id;
  buf[1] = LCD_CMD_LIGHTON;
  i2c.send(I2C_ADDR_LCD, buf, 2);
}

void LCD::lightOff()
{
  uint8_t buf[2];

  buf[0] = id;
  buf[1] = LCD_CMD_LIGHTOFF;
  i2c.send(I2C_ADDR_LCD, buf, 2);
}


void LCD::changeID(uint8_t newID)
{
  uint8_t buf[3];

  buf[0] = id;
  buf[1] = LCD_CMD_CHANGEID;
  buf[2] = newID;
  i2c.send(I2C_ADDR_LCD, buf, 3);

  id = newID;
}


#endif



