#include "TextFeeder.h"

TextFeeder::TextFeeder()
{
  gt.clear();
  graphicFrame="NULL_INDEX";
  numHeldLines=0;
  fmt.clear();
  colorR.clear();
  colorG.clear();
  colorB.clear();
  numberOfLines=-1;
  dirty=true;
}

TextFeeder::~TextFeeder()
{
}

//set graphic
const string & TextFeeder::getGraphicFrame()
{
  return graphicFrame;
}

void TextFeeder::setGraphicFrame (const string & gf)
{
  graphicFrame=gf;
}

//modify text.
//scrolls text 1 line forward. Returns false if all lines are held or there are no lines.
bool TextFeeder::scrollToNextLine ()
{
  //delete the first unheld line.

  //iterate through, check each line.
  //when you reach an unheld line, clear it and exit.
  //if you run out of lines, exit.

  vector <FormattedText> :: iterator fmtIter = fmt.begin();
  vector <FormattedText> :: iterator fmtNextLine;
  uint8_t numSkippedLines=0;
  bool done = (numHeldLines==0);

  //first, skip held lines.
  //find next line and jump ahead. End when we have skipped the number of lines or we're at the end of the text.
  while (!done)
    {
      fmtIter=getNextLine(fmtIter);
      numSkippedLines++;

      if (numSkippedLines>=numHeldLines || fmtIter==fmt.end())
        done=true;
    }

  //Return false if either there are no lines in the feeder or all lines are held. No lines were cleared.
  if (fmtIter == fmt.end())
    return false;

  //otherwise delete the next line.
  fmtNextLine=getNextLine(fmtIter);

  fmt.erase(fmtIter, fmtNextLine);
  setDirtyBit(true);
  return true;
}

//clears current text from window and fills with new text.
void TextFeeder::scrollToNextFill ()
{
  //delete the next getNumberOfLines lines.
  //repeat nextLine () getNumberOfLines times.

  if (getNumberOfLines()<=0)
    return;

  for (int i=0; i<getNumberOfLines(); i++)
    scrollToNextLine();

  setDirtyBit(true);
}

//empties all text.
void TextFeeder::empty ()
{
  fmt.clear();
  numHeldLines=0;
  setDirtyBit(true);
}

//holds the first lines of text, preventing it from being wiped or scrolled.
void TextFeeder::holdFirstLinesOfText (uint8_t index)
{
  numHeldLines=index;
}

//returns the list of formatted text.
vector <FormattedText> & TextFeeder::getFormattedText()
{
  return fmt;
}

//add colors. Return the index of the font color.
int TextFeeder::addFontColor (uint8_t r, uint8_t g, uint8_t b)
{
  colorR.push_back(r);
  colorG.push_back(g);
  colorB.push_back(b);
  return colorR.size()-1;
}

uint8_t TextFeeder::getFontColorR (int index)
{
  if (index >= 0 && index < int(colorR.size()))
    return colorR[index];

  return 0;
}

uint8_t TextFeeder::getFontColorG (int index)
{
  if (index >= 0 && index < int(colorR.size()))
    return colorG[index];

  return 0;
}

uint8_t TextFeeder::getFontColorB (int index)
{
  if (index >= 0 && index < int(colorR.size()))
    return colorB[index];

  return 0;
}

bool TextFeeder::getFontColors (int index, uint8_t & r, uint8_t & g, uint8_t & b)
{
  if (index >= 0 && index < int(colorR.size()))
    {
      r=colorR[index];
      g=colorG[index];
      b=colorB[index];
      return true;
    }

  return false;
}

//Graphic Transformation mods.
void TextFeeder::setGraphicTransformation (GraphicTransformation & g)
{
  gt = g;
}

GraphicTransformation & TextFeeder::getGraphicTransformation ()
{
  return gt;
}

//returns the number of lines the text feeder contains.
int TextFeeder::getNumberOfLines ()
{
  return numberOfLines;
}

//set the number of lines this text feeder should contain.
void TextFeeder::setNumberOfLines (int lin)
{
  numberOfLines = lin;
  setDirtyBit(true);
}

//given a position, scrolls ahead until the first item after a newline.
//If it reaches the end of the text first it returns that.
vector <FormattedText> :: iterator TextFeeder::getNextLine (vector <FormattedText> :: iterator startPoint)
{
  //advance startpoint until you see a FormattedText with newline==true.
  //OR you reach the end of formatted text.

  bool done=(startPoint==fmt.end());

  while (!done)
    {
      if (startPoint==fmt.end()||startPoint->getNewline())
        done=true;
      else
        startPoint++;
    }
  if (startPoint!=fmt.end())
    startPoint++;
  return startPoint;
}

//gets the iterator that contains the text that is visibly contained in the LineFeeder
void TextFeeder::getCurrentText(vector <FormattedText> :: iterator & fmtIterStart,
                                vector <FormattedText> :: iterator & fmtIterEnd)
{
  vector<FormattedText>::iterator fmtIter=fmt.begin();

  fmtIterStart=fmt.begin();

  int lineCount=0;

  for (lineCount=0; lineCount<getNumberOfLines(); lineCount++)
    {
      fmtIter=getNextLine(fmtIter);
    }

  fmtIterEnd=fmtIter;
}

//returns the dirty bit.
bool TextFeeder::getDirtyBit()
{
  return dirty;
}

void TextFeeder::setDirtyBit(bool d)
{
  dirty=d;
}
