/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License version   *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   This library 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     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         *
 *   02110-1301  USA                                                       *
 *                                                                         *
 *   Alternatively, this file is available under the Mozilla Public        *
 *   License Version 1.1.  You may obtain a copy of the License at         *
 *   http://www.mozilla.org/MPL/                                           *
 ***************************************************************************/

#include "ebmlmkseekhead.h"
#include "matroskaseekhead.h"
#include "ebmluintelement.h"
#include "ebmlbinaryelement.h"
#include "tdebug.h"
#include "tutils.h"

using namespace TagLib;

EBML::MkSeekHead::MkSeekHead(int sizeLength, offset_t dataSize, offset_t offset):
  MasterElement(Id::MkSeekHead, sizeLength, dataSize, offset)
{
}

EBML::MkSeekHead::MkSeekHead(Id, int sizeLength, offset_t dataSize, offset_t offset):
  MasterElement(Id::MkSeekHead, sizeLength, dataSize, offset)
{
}

EBML::MkSeekHead::MkSeekHead():
  MasterElement(Id::MkSeekHead, 0, 0, 0)
{
}

std::unique_ptr<Matroska::SeekHead> EBML::MkSeekHead::parse(offset_t segmentDataOffset) const
{
  auto seekHead = std::make_unique<Matroska::SeekHead>(segmentDataOffset);
  seekHead->setOffset(offset);
  seekHead->setSize(getSize() + padding);

  for(const auto &element : elements) {
    if(element->getId() != Id::MkSeek)
      continue;
    const auto seekElement = element_cast<Id::MkSeek>(element);
    Matroska::Element::ID entryId = 0;
    offset_t offset = -1;
    for(const auto &seekElementChild : *seekElement) {
      if(const Id id = seekElementChild->getId(); id == Id::MkSeekID && !entryId) {
        if(auto data = element_cast<Id::MkSeekID>(seekElementChild)->getValue();
           data.size() == 4)
          entryId = data.toUInt(true);
      }
      else if(id == Id::MkSeekPosition && offset < 0)
        offset = element_cast<Id::MkSeekPosition>(seekElementChild)->getValue();
    }
    if(entryId && offset >= 0)
      seekHead->addEntry(entryId, offset);
    else {
      debug(Utils::formatString("Invalid seek element: ID=0x%x, offset=%lld", entryId, offset));
    }
  }

  return seekHead;
}
