#include "savehistorywidget.h"
#include "deprecation.h"

SaveHistoryWidget::SaveHistoryWidget(QString filename, bool _dark, QWidget *parent  ):QDialog(parent){
  pvindex=-1;
  fileName=filename;
  dark=_dark;
  dda = new DragDropVersions(filename,dark,parent);
  QScrollArea *qsa = new QScrollArea();
  qsa->setWidget(dda);
  QScrollArea *preview = new QScrollArea();
  QVBoxLayout *pvla = new QVBoxLayout();
  pvheader = new QLabel("<h3>current file version</h3>"); 
  if (dark){
  pvheader->setStyleSheet (QString(
        "QLabel{font: bold; border: 2px solid #2f2f31; border-radius: 1px;background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #007700, stop: 1 #424242);} "
        "QLabel:hover {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0," "stop: 0 #242424, stop: 1 #007700);border: 2px solid #eeeeee;}"));
  }else{
  pvheader->setStyleSheet (QString(
        "QLabel{font: bold; border: 2px solid #2f2f31; border-radius: 1px;background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #aaeeaa, stop: 1 #dadbde);} "
        "QLabel:hover {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0," "stop: 0 #ffffff, stop: 1 #aaee00);border: 2px solid #eeeeee;}"));
  }
  edi = new CodeEditor();
  edi->dark=dark;
  QString inspatternfile=(dark)?":ins_res_style_dark.ini":":ins_res_style.ini";
  edi->highlighter->loadHighlightPatterns(inspatternfile);
  QFont font;
  font.setFamily(FONTFAM);
  font.setFixedPitch(true);
  font.setPointSize(9);
  edi->setFont(font);
  edi->setLineWrapMode(QPlainTextEdit::NoWrap);
  QFile p(filename);
  p.open(QIODevice::ReadOnly|QIODevice::Text);
  edi->setPlainText(orginal=p.readAll());
  p.close();
  pvla->addWidget(pvheader);
  pvla->addWidget(edi);
  edi->setReadOnly ( true);
  preview->setLayout(pvla);
  QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Open | QDialogButtonBox::Cancel);
  ok = buttonBox->button(QDialogButtonBox::Open);

  ok->setDisabled(true);
  connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
  connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
  QHBoxLayout *la = new QHBoxLayout();
  QVBoxLayout *lo = new QVBoxLayout();
  QSplitter *splitter = new QSplitter(parent);

  splitter->addWidget(qsa);
  splitter->addWidget(preview);
  splitter->setChildrenCollapsible (false);
  splitter->setStretchFactor(1, 1);
  la->addWidget(splitter);
  lo->addLayout(la);
  lo->addWidget(buttonBox);
  setLayout(lo);
  connect(dda,SIGNAL(indexChanged(int)),this,SLOT(updatePreview(int)));
  connect(dda->tick,SIGNAL(timeout()), this , SLOT(tock()));
  connect(this,SIGNAL(finished(int)), dda->tick,SLOT(stop()));
  setWindowTitle(tr("Save History"));
  this->setWindowState(Qt::WindowMaximized);
}

void SaveHistoryWidget::updatePreview(int index){
  if ((index>=0)&&(index<dda->zeiten.size())) {
    DragVersion *childle = static_cast<DragVersion *>(sender());
    if (childle){
        if (dark){
            childle->setStyleSheet (QString(
                  "QLabel{color: #ffffff; font: bold; border: 2px solid #2f2f31; border-radius: 1px;background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 %1, stop: 1 #242424);} "
                  "QLabel:hover {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,"
                  "stop: 0 #424242, stop: 1 %1);border: 0px solid #eeeeee;;}").arg("#007700"));
        } else {
      childle->setStyleSheet (QString(
            "QLabel{font: bold; border: 2px solid #2f2f31; border-radius: 1px;background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 %1, stop: 1 #dadbde);} "
            "QLabel:hover {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,"
            "stop: 0 #ffffff, stop: 1 %1);border: 0px solid #eeeeee;;}").arg("#00eeaa"));
        }
    }
    pvheader->setText(QString("<h3>%1</h3>").arg(dda->zeiten.at(index).toString()));
    pvindex=index;
    edi->setReadOnly(false);
    QString ext=dda->entries.at(index);
    ext.remove(QRegExp("^\n"));
    edi->setPlainText(ext);
    edi->diffTo(orginal);
    edi->setReadOnly(true);
  }
  else if (index==-1) {
    pvindex=index;
    pvheader->setText("<h3>current file version</h3>");
    edi->setReadOnly(false);
    QFile p(fileName);
    p.open(QIODevice::ReadOnly|QIODevice::Text);  
    edi->setPlainText(p.readAll());    
    edi->diffTo(orginal);
    p.close(); 
    edi->setReadOnly(true);
  }
}

void SaveHistoryWidget::tock(){
  if ((pvindex!=-1)&&(pvindex<dda->zeiten.size())){
    pvheader->setText(QString("<h3>%1</h3>").arg(dda->zeiten.at(pvindex).toString()));
    ok->setDisabled(false);
  }else ok->setDisabled(true);
}

void SaveHistoryWidget::accept(){
  QFile f(fileName);

  f.open(QIODevice::ReadOnly|QIODevice::Text);
  QString alterScheis=f.readAll();
  QFileInfo fi(f);
  f.close();

  bool success = f.open(QIODevice::WriteOnly|QIODevice::Text);
  if (success){
    f.write(edi->toPlainText().toLatin1());
    f.close();
    QString dn=fileName.section('/',0,-2),
            argument=fileName.section('/',-1);
    QDir work=QDir(QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
    if (!work.exists ( QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME))) work.mkdir (QString("%1/%2saves/").arg(dn).arg(PROGRAM_NAME));
    QString saveHistName=QString("%1/%2saves/SAVEHIST").arg(dn).arg(PROGRAM_NAME);
    QFile sahi(saveHistName);
    sahi.open(QIODevice::Append|QIODevice::Text);
    sahi.write(QString("Entry|@|%1|@|%2|@|\n").arg(fi.lastModified().toString(Qt::ISODate)).arg(argument).toLatin1());
    sahi.write(alterScheis.toLatin1());
  }
  done(QDialog::Accepted);
}

DragDropVersions::DragDropVersions(QString filename, bool d,QWidget *parent) :QWidget(parent){
  /*! 
   *  Gets the directory of filename and 
   *  loads in the subdirectory "PROGRAM_NAME"saves (usualy shelXlesaves/) the file SAVEHIST.
   *  In that file each entry is seperated by something like "Entry|@|2011-03-08T13:32:19|@|b11.res|@|"
   *  @param filename the file path of the res or ins file
   *  @param parent parent widget
   */
  QString dn=filename.section('/',0,-2),
          argument=filename.section('/',-1);

  QString insorres=argument;
  if (insorres.endsWith("res",Qt::CaseInsensitive)) insorres.replace(QRegExp("res$",Qt::CaseInsensitive),"ins");
  else if (insorres.endsWith("ins",Qt::CaseInsensitive)) insorres.replace(QRegExp("ins$",Qt::CaseInsensitive),"res");
  dark=d;
  current=-1;
  QString saveHistName=QString("%1/%2saves/SAVEHIST").arg(dn).arg(PROGRAM_NAME);
  QFile sahi(saveHistName);
  sahi.open(QIODevice::ReadOnly|QIODevice::Text);
  QString Alles=sahi.readAll();//Entry|@|2011-03-08T13:32:19|@|b11.res|@|
  sahi.close();
  QRegExp re = QRegExp("Entry\\|@\\|\\w+-\\w+-\\w+:\\w+:\\w+\\|@\\|[^@]+@\\|");
  entries = Alles.split(re,skipEmptyParts);
  int pos = re.indexIn(Alles);
  QStringList filenames;
  while (pos>-1) {
    zeiten.append(QDateTime::fromString(re.cap(0).section('|',2,2),Qt::ISODate));
    filenames.append(re.cap(0).section('|',4,4));
    re.indexIn(Alles,pos+30);
    pos=re.pos(0);
  }
  now = QDateTime::currentDateTime();
  for (int j=0; j<filenames.size(); j++)
    for (int i=0; i<filenames.size(); i++){
      if ((filenames.at(i)!=argument)&&(filenames.at(i)!=insorres)){
        entries.removeAt(i);
        zeiten.removeAt(i);
        filenames.removeAt(i);          
      }
    }
  int x = 5;
  int y = 5;
  int row=0,lawi=0,ymax=0;
  DragVersion * l;
  uint beast=666;
  l =new DragVersion(-1,QString("current file version"),beast, -1, dark, this);
  l->move(5, 5);
  l->show();
  breite = lawi = itemwidth=l->width()+25;
  hoehe = l->height()+25;
  x=lawi+5;
  for (int i=0; i<zeiten.size(); i++){
    DragVersion *wordLabel = new DragVersion(i,zeiten.at(i).toString(),zeiten.at(i).toTime_t(),-1,dark , this);
    wordLabel->move(x, y);
    wordLabel->show();
    wordLabel->setAttribute(Qt::WA_DeleteOnClose);
    itemheight=wordLabel->height();
    itemwidth = qMax(wordLabel->width()+25,itemwidth);
    y += wordLabel->height() + 2;
    ymax=qMax(ymax,y+itemheight);
    if (y / height()) {
      lawi = itemwidth;
      row++; 
    }
    x = (y / height())? lawi+x-20 : x;
    y = (y / height())? 5 : y;
  }// */

  QPalette newPalette = palette();
  newPalette.setColor(QPalette::Window, Qt::white);
  setPalette(newPalette);

  setFixedSize(itemwidth+x+5, qMax(200, ymax));
  tick = new QTimer(this);
  connect(tick,SIGNAL(timeout()), this , SLOT(tack()));
  tick->start(500);
  setAcceptDrops(true);
}

void DragDropVersions::paintEvent(QPaintEvent *event){
  QPainter p(this);
  p.fillRect(event->rect(), (dark)?QColor("#455364"):QColor("#eeeeee"));
  p.fillRect(0, 0, breite, hoehe, QColor("#aac0cc"));
}

void DragDropVersions::tack(){
  QObjectList kinder =children () ;
  now = QDateTime::currentDateTime(); 
  for (int i=0; i<kinder.size(); i++){
    DragVersion *child = static_cast<DragVersion*>(kinder.at(i));
    if (!child||!child->inherits("QLabel")) continue;
    int idx=child->index();
    if ((idx==-1)&&(child->secs()==666)) {
        if (dark)child->setStyleSheet (QString(
                          "QLabel{color: #ffffff; font: bold; border: 2px solid #2f2f31; border-radius: 1px;background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 %1, stop: 1 #242424);} "
                          "QLabel:hover {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,"
                          "stop: 0 #424242, stop: 1 %1);border: 0px solid #eeeeee;;}").arg((idx==current)?"#007799":"#007700"));
        else child->setStyleSheet (QString(
            "QLabel{font: bold; border: 2px solid #2f2f31; border-radius: 1px;background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 %1, stop: 1 #dadbde);} "
            "QLabel:hover {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,"
            "stop: 0 #ffffff, stop: 1 %1);border: 2px solid #eeeeee;}").arg(QColor((idx==current)?"#aaeeaa":"#ffeecc").name()));
    }
    if ((idx<0)||(idx>=zeiten.size())||(child->secs()==666)) continue;
    //child->setText(seitkurzem(now.secsTo(QDateTime::fromTime_t (child->secs()))));
    child->setText(QDateTime::fromTime_t (child->secs()).toString());
    if (dark)child->setStyleSheet (QString(
                      "QLabel{color: #ffffff; font: bold; border: 2px solid #2f2f31; border-radius: 1px;background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 %1, stop: 1 #242424);} "
                      "QLabel:hover {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,"
                      "stop: 0 #424242, stop: 1 %1);border: 0px solid #eeeeee;;}").arg((idx==current)?"#007799":"#007700"));
    else child->setStyleSheet (QString(
          "QLabel{font: bold; border: 2px solid #2f2f31; border-radius: 1px;background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 %1, stop: 1 #dadbde);} "
          "QLabel:hover {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,"
          "stop: 0 #ffffff, stop: 1 %1);border: 2px solid #eeeeee;}").arg(QColor((idx==current)?"#aaeeaa":"#ffeecc").name()));
    child->adjustSize ();
  }// */
}

void DragDropVersions::mousePressEvent(QMouseEvent *event){
  DragVersion *child = static_cast<DragVersion*>(childAt(event->pos()));
  if (!child)
    return;
  current = child->index();
  emit indexChanged(current);
}

////////////////////////////////////////////////////////////////////////////////
DragVersion::DragVersion(const int index,const QString &text, uint secs,const int cur, bool d, QWidget *parent): QLabel(parent){
  m_labelText = text;
  m_index = index;
  m_secs = secs;
  dark=d;
  setText(m_labelText);
  if (dark){
  setStyleSheet (QString(
        "QLabel{color: #ffffff; font: bold; border: 2px solid #2f2f31; border-radius: 1px;background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 %1, stop: 1 #242424);} "
        "QLabel:hover {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,"
        "stop: 0 #424242, stop: 1 %1);border: 0px solid #eeeeee;;}").arg((index==cur)?"#007799":"#007700"));
}else{
  setStyleSheet (QString(
        "QLabel{font: bold; border: 2px solid #2f2f31; border-radius: 1px;background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 %1, stop: 1 #dadbde);} "
        "QLabel:hover {background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,"
        "stop: 0 #ffffff, stop: 1 %1);border: 2px solid #eeeeee;}").arg(QColor((index==cur)?"#aaeeaa":"#ffeecc").name()));
  }
}

QString DragVersion::labelText() const{
  return m_labelText;
}

int DragVersion::index() const{
  return m_index;
}

uint DragVersion::secs() const{
  return m_secs;
}

