/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
 *            macrowindow.cc
 *
 *  Fri Aug 31 12:27:45 CEST 2007
 *  Copyright 2007 Lars Bisballe Jensen and Bent Bisballe Nyeng
 *  elsenator@gmail.com and deva@aasimon.org
 ****************************************************************************/

/*
 *  This file is part of Pracro.
 *
 *  Pracro is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  Pracro is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Pracro; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 */
#include "macrowindow.h"
#include "sendrecieve.h"
#include "macro.h"
#include "widgets/widget.h"
#include <QVBoxLayout>
#include <QMessageBox>
#include <QDomDocument>
#include <QDomElement>
#include <QDomNode>
#include <QByteArray>

#include "widgets/window.h"
#include "widgetbuilder.h"
#include "lua.h"

extern QString cpr;
extern QString user;
extern QString host;
extern quint16 port;

MacroWindow::MacroWindow(QDomNode &xml_doc)
  : QObject()
{
  isclosed = false;
  mainwidget = NULL;

  this->lua = new LUA(this);

  initMacro(xml_doc);

  if(mainwidget) mainwidget->show();
}

MacroWindow::~MacroWindow()
{
  delete lua;
}

void MacroWindow::initMacro(QDomNode &node)
{
  QDomElement xml_elem = node.toElement();

  if(xml_elem.tagName() == "macro") {
    // Assign the macro name and version to QStrings for use when comitting
    if(xml_elem.hasAttribute("name")) macro = xml_elem.attribute("name");
    if(xml_elem.hasAttribute("version")) version = xml_elem.attribute("version");

  } else if(xml_elem.tagName() == "luaprograms") {
    // Nothing to do here
  } else if(xml_elem.tagName() == "luaprogram") {

    if(xml_elem.hasAttribute("name")) {
      luaprograms[xml_elem.attribute("name")] = xml_elem.text();
    }

  } else if(xml_elem.tagName() == "window") {
    Window *window = new Window(xml_elem, this);
    mainwidget = window;

    QDomNodeList children = node.childNodes();

    for (int i=0; i<children.count();i++) {
      QDomNode child = children.at(i);
      widgets += widgetBuilder(child, mainwidget, this);
    }
    return;
  }

  QDomNodeList children = node.childNodes();

  for (int i=0; i<children.count();i++) {
    QDomNode child = children.at(i);
    initMacro(child);
  }

}

bool MacroWindow::doCommit()
{
  // Check for, and count, errors on all entries before comitting
  int faulty = 0; // 0 initial errors

  QVector< Widget* >::iterator i = widgets.begin();
  while (i != widgets.end()) {
    Widget* w = *i;
    if(!w->isValid()) faulty++; // Regexp check, returns valid if entry passed
    i++;
  }

  // If all entries passed validation, continue commit
  if(faulty == 0) {
    printf("MacroWindow -> committing...\n");
    
    // Build the XML commit
    QString xml_string;
    xml_string.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
    xml_string.append("<pracro version=\"1.0\" cpr=\"" + cpr + "\" user=\"" + user + "\">\n");
    xml_string.append("  <commit macro=\"" + macro + "\" version=\"" + 
		      version + "\">\n");

    // Iterate the different entries, and append their results to the commit string
    QVector< Widget* >::iterator i=widgets.begin();
    while (i != widgets.end()) {
      Widget* w = *i;
      
      xml_string.append("    <field name=\"" + w->getName()
		     + "\" value=\"" + w->getValue() + "\"/>\n");
      i++;
    }
    
    xml_string.append("  </commit>\n");
    xml_string.append("</pracro>\n");
    
    // Print commit to stdout for debug purposes
    printf("%s\n", xml_string.toStdString().c_str());

    // Convert the commit to Utf-8 charset
    QByteArray xml_array = xml_string.toUtf8();
    QDomDocument xml_result;

    // Use setContent of QDomDocument to validate the xml commit
    if (!xml_result.setContent(xml_array)) {
      printf("Parse error: Invalid XML\n");
    }
    
    // Commit the xml data to the server
    SendRecieve macro_commit(host, port);
    macro_commit.makeConnection(&xml_result);
    // Recieve answer from server whether successful or not
    //QByteArray ba = macro_commit.getResult();
    QString ba = macro_commit.getResult();
    printf("Server returned result: %s", ba.toStdString().c_str());
    return true;
  } else {
    return false;
  }
}

void MacroWindow::close()
{
  mainwidget->close();
  isclosed = true;
}

void MacroWindow::commit()
{
  if(doCommit()) {
    close();
  } else {
   QMessageBox::critical(NULL, "Fejl",
			  "Makroen er ikke udfyldt korrekt, pr�v igen.\n"
			  , QMessageBox::Ok);
  }
}

void MacroWindow::reset()
{
  QMessageBox::warning(NULL, tr("Reset"),
                   tr("Du har valgt at nulstille de indtastede data.\n"
                      "Er du sikker?"),
                   QMessageBox::Yes | QMessageBox::Cancel);
  printf("MacroWindow -> resetting...\n");
}

void MacroWindow::cancel()
{
  printf("MacroWindow -> cancelling...\n");
  close();
}

void MacroWindow::cont(QString name)
{
  QString macro;
  QVector< Widget* >::iterator i=widgets.begin();
  while (i != widgets.end()) {
    Widget* w = *i;
    if(w->getName() == name) {
      macro = w->getValue();
    }
    i++;
  }
  if(doCommit()) {
    new_macro("FIXME", macro);
    close();
  } else {
   QMessageBox::critical(NULL, "Fejl",
			 "Makroen er ikke udfyldt korrekt, pr�v igen.\n",
			 QMessageBox::Ok);
  }
  printf("%s : MacroWindow -> continuing...\n", macro.toStdString().c_str());
}

bool MacroWindow::isClosed()
{
  return isclosed;
}

QString MacroWindow::getValue(QString name)
{
  // Iterate the different entries, and append their results to the commit string
  QVector< Widget* >::iterator i=widgets.begin();
  while (i != widgets.end()) {
    Widget* w = *i;
    if(name == w->getName()) return w->getValue();
    i++;
  }
  return name + " - No such field!";
}

void MacroWindow::setValue(QString name, QString value)
{
  // Iterate the different entries, and append their results to the commit string
  QVector< Widget* >::iterator i = widgets.begin();
  while (i != widgets.end()) {
    Widget* w = *i;
    if(name == w->getName()) w->setValue(value);
    i++;
  }
}