/**********************************************************************************************
    Copyright (C) 2014 Oliver Eichler <oliver.eichler@gmx.de>

    This program 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 3 of the License, or
    (at your option) any later version.

    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

**********************************************************************************************/

#include "IQlgtOverlay.h"

struct ovl_head_entry_t {
  ovl_head_entry_t() : type(IQlgtOverlay::eEnd), offset(0) {}
  qint32 type;
  quint32 offset;
  QByteArray data;
};

QDataStream& operator>>(QDataStream& s, IQlgtOverlay& ovl) {
  QIODevice* dev = s.device();
  qint64 pos = dev->pos();

  char magic[9];
  s.readRawData(magic, 9);

  if (strncmp(magic, "QLOvl   ", 9)) {
    dev->seek(pos);
    return s;
  }

  QList<ovl_head_entry_t> entries;

  while (1) {
    ovl_head_entry_t entry;
    s >> entry.type >> entry.offset;
    entries << entry;
    if (entry.type == IQlgtOverlay::eEnd) {
      break;
    }
  }

  QList<ovl_head_entry_t>::iterator entry = entries.begin();
  while (entry != entries.end()) {
    qint64 o = pos + entry->offset;
    dev->seek(o);
    s >> entry->data;

    switch (entry->type) {
      case IQlgtOverlay::eBase: {
        QDataStream s1(&entry->data, QIODevice::ReadOnly);
        s1.setVersion(QDataStream::Qt_4_5);

        s1 >> ovl.type;
        if (ovl.type == "Text") {
          QRect rect;
          QString text;
          s1 >> rect >> text >> ovl.key;
        } else if (ovl.type == "TextBox") {
          QRect rect;
          QPoint pt;
          QString text;
          double lon, lat;
          s1 >> lon >> lat >> pt >> rect >> text >> ovl.key;
        } else if (ovl.type == "Distance") {
          int size, idx = 0;
          IQlgtOverlay::pt_t pt;
          s1 >> ovl.name >> ovl.comment >> size;
          for (int i = 0; i < size; ++i) {
            s1 >> pt.u >> pt.v;
            pt.idx = idx++;
            ovl.points << pt;
          }
          s1 >> ovl.speed >> ovl.key >> ovl.parentWpt;
        } else if (ovl.type == "Area") {
          int size, idx = 0;
          IQlgtOverlay::pt_t pt;
          s1 >> ovl.name >> ovl.comment >> size;
          for (int i = 0; i < size; ++i) {
            s1 >> pt.u >> pt.v;
            pt.idx = idx++;
            ovl.points << pt;
          }
          s1 >> ovl.color >> ovl.key >> ovl.parentWpt >> ovl.style >> ovl.width >> ovl.opacity;
        }
        break;
      }

      default:;
    }

    ++entry;
  }

  return s;
}

QDataStream& operator<<(QDataStream& s, IQlgtOverlay& ovl) {
  QList<ovl_head_entry_t> entries;

  //---------------------------------------
  // prepare base data
  //---------------------------------------
  ovl_head_entry_t entryBase;
  entryBase.type = IQlgtOverlay::eBase;
  QDataStream s1(&entryBase.data, QIODevice::WriteOnly);
  s1.setVersion(QDataStream::Qt_4_5);
  s1 << ovl.type;
  //    ovl.save(s1);
  entries << entryBase;

  //---------------------------------------
  // prepare terminator
  //---------------------------------------
  ovl_head_entry_t entryEnd;
  entryEnd.type = IQlgtOverlay::eEnd;
  entries << entryEnd;

  //---------------------------------------
  //---------------------------------------
  // now start to actually write data;
  //---------------------------------------
  //---------------------------------------
  // write magic key
  s.writeRawData("QLOvl   ", 9);

  // calculate offset table
  quint32 offset = entries.count() * 8 + 9;

  QList<ovl_head_entry_t>::iterator entry = entries.begin();
  while (entry != entries.end()) {
    entry->offset = offset;
    offset += entry->data.size() + sizeof(quint32);
    ++entry;
  }

  // write offset table
  entry = entries.begin();
  while (entry != entries.end()) {
    s << entry->type << entry->offset;
    ++entry;
  }

  // write entry data
  entry = entries.begin();
  while (entry != entries.end()) {
    s << entry->data;
    ++entry;
  }

  return s;
}

IQlgtOverlay::IQlgtOverlay(quint64 id, QObject* parent) : IItem(id) {}

IQlgtOverlay::~IQlgtOverlay() {}
