#include "subtitles.h"

Subtitles::Subtitles(const char *filename)
{
  m_frame_based=0;
  m_last_sub=-1;
  m_font_size_mod=0;

#ifdef SUBTITLES_READER
  if(!filename) return;

  IDataReader *file_reader=CreateReader(filename);
  if(file_reader) {
    char *text=NULL;
    int textpos=0;
    int allocsize=0;
    char buf[1024] = {0};
    unsigned aborttime=GetTickCount()+20000;
    for (;;)
    {
      int l=file_reader->read(buf,1024);
      if (l <= 0) 
      {
        if (file_reader->iseof()) break;
        if (file_reader->geterror() || GetTickCount() > aborttime) 
        {
          free(text);
          return;
        }
        Sleep(100);
      }
      else
      {
        if (textpos+l+1 >= allocsize)
        {
          allocsize = textpos+l+1+8192;
          text=(char*)realloc(text,allocsize);
        }
        memcpy(text+textpos,buf,l);
        textpos+=l;
      }
    }
    if (text) {
      text[textpos]=0;
      //fucko: check for case
      if(strstr(filename,".srt")) decodeSrtFile(text);
      else if(strstr(filename,".sub")) decodeSubFile(text);
      free(text);
    }
  }
  delete(file_reader);
#endif
}

#ifdef SUBTITLES_READER
void Subtitles::decodeSrtFile(char *text) {
  // parse subtitle file (.srt format)
  char *p=text;

  //for(int i=0;;i++) {
  while(1) {
    unsigned int time_start,time_end;

    // parse title nb
    char *p2=p;
    while(*p2 && *p2!='\n') p2++;
    *p2++=0;
    //if(atoi(p)!=i+1) break;
    if(atoi(p)<=0) break;
      
    // parse start time
    p=p2;
    while(*p2 && *p2!=' ') p2++;
    *p2++=0;
    time_start=getTimeFromSrtText(p);

    // parse "-->"
    while(*p2 && *p2!=' ') p2++;
    p2++;
    
    // parse end time
    p=p2;
    while(*p2 && *p2!='\n') p2++;
    *p2++=0;
    time_end=getTimeFromSrtText(p);

    // parse text
    p=p2;
    while(*p2 && !(*p2=='\r' || *p=='\n')) {
      while(*p2 && *p2!='\n') p2++;
      p2++;
    }
    *p2++=0;

    //remove trailing CR
    {
      int l=strlen(p);
      if(l) {
        if(p[l-1]=='\r' || p[l-1]=='\n') p[l-1]=0;
      }
    }

    m_subs.put(new SubsItem(time_start,time_end,p));

    if(*p2=='\n') p2++;
    p=p2;
  }
  m_frame_based=0;
}

unsigned int Subtitles::getTimeFromSrtText(const char *text) {
  int hours,mins,secs,mills;
  const char *p=text;
  hours=atoi(p);
  while(*p && *p!=':') p++;
  p++;
  mins=atoi(p);
  while(*p && *p!=':') p++;
  p++;
  secs=atoi(p);
  while(*p && *p!=',') p++;
  p++;
  mills=atoi(p);
  return mills+(secs*1000)+(mins*60000)+(hours*60*60000);
}

void Subtitles::decodeSubFile(char *text)
{
  char *p=text;
  while(*p=='{') {
    int framestart,frameend;
    p++;
    char *p2=p;
    while(*p2 && *p2!='}') p2++;
    *p2++=0;
    framestart=atoi(p);

    p2+=1;
    p=p2;
    while(*p2 && *p2!='}') p2++;
    *p2++=0;
    frameend=atoi(p);

    p=p2;
    while(*p2 && *p2!='\r' && *p2!='\n') {
      //replace pipes with CR
      if(*p2=='|') *p2='\n';
      p2++;
    }
    *p2++=0;
    
    m_subs.put(new SubsItem(framestart,frameend,p));

    if(*p2=='\n') p2++;
    p=p2;
  }
  m_frame_based=1;
}
#endif

SubsItem *Subtitles::getSubtitle(unsigned int time, unsigned int frame)
{
  unsigned int ref=m_frame_based?frame:time;

  //check with lastsub
  if(m_last_sub!=-1) {
    SubsItem *item=m_subs.get(m_last_sub);
    if(ref>=item->timestart && ref<=item->timeend) 
    {
      item->fontSize=item->origFontSize+m_font_size_mod;
      return item;
    }
    SubsItem *item2=m_subs.get(m_last_sub+1);
    if(item2) {
      if(ref>=item->timeend && ref<=item2->timestart) return NULL;
      if(ref>=item2->timestart && ref<=item2->timeend) {
        m_last_sub++;
        item2->fontSize=item2->origFontSize+m_font_size_mod;
        return item2;
      }
    }
  } 

  int l= (int)m_subs.getlen();
  for(int i=0;i<l;i++) {
    SubsItem *item=m_subs.get(i);
    if(ref<item->timestart) break;
    if(ref>=item->timestart && ref<=item->timeend) {
      m_last_sub=i;
      item->fontSize=item->origFontSize+m_font_size_mod;
      return item;
    }
  }
  m_last_sub=-1;
  return NULL;
}

void Subtitles::addSubtitlePacket(SUBTITLE_INFO *sti) 
{
  m_frame_based=1; //FUCKO: put this in subsitem struct
  SubsItem *i=new SubsItem(sti->start_frame,sti->end_frame,sti->utf8_text);
  i->xPos=sti->xPos;
  i->yPos=sti->yPos;
  i->colorBlue=sti->colorBlue;
  i->colorGreen=sti->colorGreen;
  i->colorRed=sti->colorRed;
  i->extraDataSize=sti->extraDataSize;
  i->origFontSize=sti->fontSize;
  if(sti->extraDataSize) {
    i->extraData=malloc(sti->extraDataSize);
    memcpy((void *)i->extraData,sti->extraData,sti->extraDataSize);
  }
  i->muxed_subtitle=1;
  m_subs.put(i);
}