/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 * The Original Code is MPEG4IP.
 *
 * The Initial Developer of the Original Code is Cisco Systems Inc.
 * Portions created by Cisco Systems Inc. are
 * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
 *
 * Contributor(s):
 *      Dave Mackie     dmackie@cisco.com
 *      Kona Blend      kona8lend@@gmail.com
 */

#include "src/impl.h"

namespace mp4v2 { namespace impl {

///////////////////////////////////////////////////////////////////////////////

MP4Property::MP4Property(MP4Atom& parentAtom, const char* name)
    : m_parentAtom(parentAtom)
{
    m_name = name;
    m_readOnly = false;
    m_implicit = false;
}

bool MP4Property::FindProperty(const char* name,
                               MP4Property** ppProperty, uint32_t* pIndex)
{
    if (name == NULL) {
        return false;
    }

    if (!strcasecmp(m_name, name)) {
        log.verbose1f("\"%s\": FindProperty: matched %s", 
                      m_parentAtom.GetFile().GetFilename().c_str(), name);
        *ppProperty = this;
        return true;
    }
    return false;
}

// Integer Property

uint64_t MP4IntegerProperty::GetValue(uint32_t index)
{
    switch (this->GetType()) {
    case Integer8Property:
        return ((MP4Integer8Property*)this)->GetValue(index);
    case Integer16Property:
        return ((MP4Integer16Property*)this)->GetValue(index);
    case Integer24Property:
        return ((MP4Integer24Property*)this)->GetValue(index);
    case Integer32Property:
        return ((MP4Integer32Property*)this)->GetValue(index);
    case Integer64Property:
        return ((MP4Integer64Property*)this)->GetValue(index);
    default:
        ASSERT(false);
    }
    return (0);
}

void MP4IntegerProperty::SetValue(uint64_t value, uint32_t index)
{
    switch (this->GetType()) {
    case Integer8Property:
        ((MP4Integer8Property*)this)->SetValue(value, index);
        break;
    case Integer16Property:
        ((MP4Integer16Property*)this)->SetValue(value, index);
        break;
    case Integer24Property:
        ((MP4Integer24Property*)this)->SetValue(value, index);
        break;
    case Integer32Property:
        ((MP4Integer32Property*)this)->SetValue(value, index);
        break;
    case Integer64Property:
        ((MP4Integer64Property*)this)->SetValue(value, index);
        break;
    default:
        ASSERT(false);
    }
}

void MP4IntegerProperty::InsertValue(uint64_t value, uint32_t index)
{
    switch (this->GetType()) {
    case Integer8Property:
        ((MP4Integer8Property*)this)->InsertValue(value, index);
        break;
    case Integer16Property:
        ((MP4Integer16Property*)this)->InsertValue(value, index);
        break;
    case Integer24Property:
        ((MP4Integer24Property*)this)->InsertValue(value, index);
        break;
    case Integer32Property:
        ((MP4Integer32Property*)this)->InsertValue(value, index);
        break;
    case Integer64Property:
        ((MP4Integer64Property*)this)->InsertValue(value, index);
        break;
    default:
        ASSERT(false);
    }
}

void MP4IntegerProperty::DeleteValue(uint32_t index)
{
    switch (this->GetType()) {
    case Integer8Property:
        ((MP4Integer8Property*)this)->DeleteValue(index);
        break;
    case Integer16Property:
        ((MP4Integer16Property*)this)->DeleteValue(index);
        break;
    case Integer24Property:
        ((MP4Integer24Property*)this)->DeleteValue(index);
        break;
    case Integer32Property:
        ((MP4Integer32Property*)this)->DeleteValue(index);
        break;
    case Integer64Property:
        ((MP4Integer64Property*)this)->DeleteValue(index);
        break;
    default:
        ASSERT(false);
    }
}

void MP4IntegerProperty::IncrementValue(int32_t increment, uint32_t index)
{
    SetValue(GetValue() + increment);
}

void MP4Integer8Property::Dump(uint8_t indent,
                               bool dumpImplicits, uint32_t index)
{
    if (m_implicit && !dumpImplicits) {
        return;
    }
    if (index != 0)
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s[%u] = %u (0x%02x)",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, index, m_values[index], m_values[index]);
    else
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s = %u (0x%02x)",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, m_values[index], m_values[index]);
}

void MP4Integer16Property::Dump(uint8_t indent,
                                bool dumpImplicits, uint32_t index)
{
    if (m_implicit && !dumpImplicits) {
        return;
    }
    if (index != 0)
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s[%u] = %u (0x%04x)",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, index, m_values[index], m_values[index]);
    else
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s = %u (0x%04x)",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, m_values[index], m_values[index]);
}

void MP4Integer24Property::Dump(uint8_t indent,
                                bool dumpImplicits, uint32_t index)
{
    if (m_implicit && !dumpImplicits) {
        return;
    }
    if (index != 0)
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s[%u] = %u (0x%06x)",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, index, m_values[index], m_values[index]);
    else
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s = %u (0x%06x)",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, m_values[index], m_values[index]);
}

void MP4Integer32Property::Dump(uint8_t indent,
                                bool dumpImplicits, uint32_t index)
{
    if (m_implicit && !dumpImplicits) {
        return;
    }
    if (index != 0)
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s[%u] = %u (0x%08x)",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, index, m_values[index], m_values[index]);
    else
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s = %u (0x%08x)",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, m_values[index], m_values[index]);
}

void MP4Integer64Property::Dump(uint8_t indent,
                                bool dumpImplicits, uint32_t index)
{
    if (m_implicit && !dumpImplicits) {
        return;
    }
    if (index != 0)
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s[%u] = %" PRIu64 " (0x%016" PRIx64 ")",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, index, m_values[index], m_values[index]);
    else
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s = %" PRIu64 " (0x%016" PRIx64 ")",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, m_values[index], m_values[index]);
}

// MP4BitfieldProperty

void MP4BitfieldProperty::Read(MP4File& file, uint32_t index)
{
    if (m_implicit) {
        return;
    }
    m_values[index] = file.ReadBits(m_numBits);
}

void MP4BitfieldProperty::Write(MP4File& file, uint32_t index)
{
    if (m_implicit) {
        return;
    }
    file.WriteBits(m_values[index], m_numBits);
}

void MP4BitfieldProperty::Dump(uint8_t indent,
                               bool dumpImplicits, uint32_t index)
{
    if (m_implicit && !dumpImplicits) {
        return;
    }
    uint8_t hexWidth = m_numBits / 4;
    if (hexWidth == 0 || (m_numBits % 4)) {
        hexWidth++;
    }
    if (index != 0)
        log.dump(indent, MP4_LOG_VERBOSE1,
                 "\"%s\": %s[%u] = %" PRIu64 " (0x%0*" PRIx64 ") <%u bits>",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, index, m_values[index], (int)hexWidth, m_values[index], m_numBits);
    else
        log.dump(indent, MP4_LOG_VERBOSE1,
                 "\"%s\": %s = %" PRIu64 " (0x%0*" PRIx64 ") <%u bits>",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, m_values[index], (int)hexWidth, m_values[index], m_numBits);
}

// MP4Float32Property

void MP4Float32Property::Read(MP4File& file, uint32_t index)
{
    if (m_implicit) {
        return;
    }
    if (m_useFixed16Format) {
        m_values[index] = file.ReadFixed16();
    } else if (m_useFixed32Format) {
        m_values[index] = file.ReadFixed32();
    } else {
        m_values[index] = file.ReadFloat();
    }
}

void MP4Float32Property::Write(MP4File& file, uint32_t index)
{
    if (m_implicit) {
        return;
    }
    if (m_useFixed16Format) {
        file.WriteFixed16(m_values[index]);
    } else if (m_useFixed32Format) {
        file.WriteFixed32(m_values[index]);
    } else {
        file.WriteFloat(m_values[index]);
    }
}

void MP4Float32Property::Dump(uint8_t indent,
                              bool dumpImplicits, uint32_t index)
{
    if (m_implicit && !dumpImplicits) {
        return;
    }
    if (index != 0)
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s[%u] = %f",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, index, m_values[index]);
    else
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s = %f",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, m_values[index]);
}

// MP4StringProperty

MP4StringProperty::MP4StringProperty(
    MP4Atom& parentAtom,
    const char* name,
    bool        useCountedFormat,
    bool        useUnicode,
    bool        arrayMode )

    : MP4Property( parentAtom, name )
    , m_arrayMode        ( arrayMode )
    , m_useCountedFormat ( useCountedFormat )
    , m_useExpandedCount ( false )
    , m_useUnicode       ( useUnicode )
    , m_fixedLength      ( 0 )
{
    SetCount( 1 );
    m_values[0] = NULL;
}

MP4StringProperty::~MP4StringProperty()
{
    uint32_t count = GetCount();
    for (uint32_t i = 0; i < count; i++) {
        MP4Free(m_values[i]);
    }
}

void MP4StringProperty::SetCount(uint32_t count)
{
    uint32_t oldCount = m_values.Size();

    m_values.Resize(count);

    for (uint32_t i = oldCount; i < count; i++) {
        m_values[i] = NULL;
    }
}

void MP4StringProperty::SetValue(const char* value, uint32_t index)
{
    if (m_readOnly) {
        ostringstream msg;
        msg << "property " << m_name << "is read-only";
        throw new PlatformException(msg.str().c_str(), EACCES, __FILE__, __LINE__, __FUNCTION__ );
    }

    MP4Free(m_values[index]);

    if (m_fixedLength) {
        m_values[index] = (char*)MP4Calloc(m_fixedLength + 1);
        if (value) {
            strncpy(m_values[index], value, m_fixedLength);
        }
    } else {
        if (value) {
            m_values[index] = MP4Stralloc(value);
        } else {
            m_values[index] = NULL;
        }
    }
}

void MP4StringProperty::Read( MP4File& file, uint32_t index )
{
    if( m_implicit )
        return;

    uint32_t begin = index;
    uint32_t max   = index + 1;

    if( m_arrayMode ) {
        begin = 0;
        max   = GetCount();
    }

    for( uint32_t i = begin; i < max; i++ ) {
        char*& value = m_values[i];

        // Generally a default atom setting, e.g. see atom_avc1.cpp, "JVT/AVC Coding"; we'll leak this string if
        // we don't free.  Note that MP4Free checks for null.
        MP4Free(value); 

        if( m_useCountedFormat ) {
            value = file.ReadCountedString( (m_useUnicode ? 2 : 1), m_useExpandedCount, m_fixedLength );
        }
        else if( m_fixedLength ) {
            value = (char*)MP4Calloc( m_fixedLength + 1 );
            file.ReadBytes( (uint8_t*)value, m_fixedLength );
        }
        else {
            value = file.ReadString();
        }
    }
}

void MP4StringProperty::Write( MP4File& file, uint32_t index )
{
    if( m_implicit )
        return;

    uint32_t begin = index;
    uint32_t max   = index + 1;

    if( m_arrayMode ) {
        begin = 0;
        max   = GetCount();
    }

    for( uint32_t i = begin; i < max; i++ ) {
        char*& value = m_values[i];

        if( m_useCountedFormat ) {
            file.WriteCountedString( value, (m_useUnicode ? 2 : 1), m_useExpandedCount, m_fixedLength );
        }
        else if( m_fixedLength ) {
            file.WriteBytes( (uint8_t*)value, m_fixedLength );
        }
        else {
            file.WriteString( value );
        }
    }
}

void MP4StringProperty::Dump( uint8_t indent, bool dumpImplicits, uint32_t index )
{
    if( m_implicit && !dumpImplicits )
        return;

    if( !m_arrayMode ) {
        char indexd[32];
        if( index != 0 )
            snprintf( indexd, 32, "[%u]", index );
        else
            indexd[0] = '\0';

        if( m_useUnicode )
            log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s%s = %ls",
                     m_parentAtom.GetFile().GetFilename().c_str(),
                     m_name, indexd, (wchar_t*)m_values[index] );
        else
            log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s%s = %s",
                     m_parentAtom.GetFile().GetFilename().c_str(),
                     m_name, indexd, m_values[index] );
    }
    else if( log.verbosity >= MP4_LOG_VERBOSE2 )
    {
        const uint32_t max = GetCount();

        log.dump(indent, MP4_LOG_VERBOSE2, "\"%s\": %s (size=%u)",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, max );

        for( uint32_t i = 0; i < max; i++ ) {
            char*& value = m_values[i];

            if( m_useUnicode )
                log.dump(indent, MP4_LOG_VERBOSE2, "\"%s\": %s[%u] = %ls",
                         m_parentAtom.GetFile().GetFilename().c_str(),
                         m_name, i, (wchar_t*)value );
            else
                log.dump(indent, MP4_LOG_VERBOSE2, "\"%s\": %s[%u] = %s",
                         m_parentAtom.GetFile().GetFilename().c_str(),
                         m_name, i, value );
        }
    }
    else {
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": <table entries suppressed>",
                 m_parentAtom.GetFile().GetFilename().c_str() );
    }
}

// MP4BytesProperty

MP4BytesProperty::MP4BytesProperty(MP4Atom& parentAtom, const char* name, uint32_t valueSize,
                                   uint32_t defaultValueSize)
        : MP4Property(parentAtom, name)
        , m_fixedValueSize(0)
        , m_defaultValueSize(defaultValueSize)
{
    SetCount(1);
    m_values[0] = (uint8_t*)MP4Calloc(valueSize);
    m_valueSizes[0] = valueSize;
}

MP4BytesProperty::~MP4BytesProperty()
{
    uint32_t count = GetCount();
    for (uint32_t i = 0; i < count; i++) {
        MP4Free(m_values[i]);
    }
}

void MP4BytesProperty::SetCount(uint32_t count)
{
    uint32_t oldCount = m_values.Size();

    m_values.Resize(count);
    m_valueSizes.Resize(count);

    for (uint32_t i = oldCount; i < count; i++) {
        m_values[i] = NULL;
        m_valueSizes[i] = m_defaultValueSize;
    }
}

void MP4BytesProperty::SetValue(const uint8_t* pValue, uint32_t valueSize,
                                uint32_t index)
{
    if (m_readOnly) {
        ostringstream msg;
        msg << "property " << m_name << "is read-only";
        throw new PlatformException(msg.str().c_str(), EACCES, __FILE__, __LINE__, __FUNCTION__ );
    }
    if (m_fixedValueSize) {
        if (valueSize > m_fixedValueSize) {
            ostringstream msg;
            msg << GetParentAtom().GetType() << "." << GetName() << " value size " << valueSize << " exceeds fixed value size " << m_fixedValueSize;
            throw new Exception(msg.str().c_str(), __FILE__, __LINE__, __FUNCTION__ );
        }
        if (m_values[index] == NULL) {
            m_values[index] = (uint8_t*)MP4Calloc(m_fixedValueSize);
            m_valueSizes[index] = m_fixedValueSize;
        }
        if (pValue) {
            memcpy(m_values[index], pValue, valueSize);
        }
    } else {
        MP4Free(m_values[index]);
        if (pValue) {
            m_values[index] = (uint8_t*)MP4Malloc(valueSize);
            memcpy(m_values[index], pValue, valueSize);
            m_valueSizes[index] = valueSize;
        } else {
            m_values[index] = NULL;
            m_valueSizes[index] = 0;
        }
    }
}

void MP4BytesProperty::SetValueSize(uint32_t valueSize, uint32_t index)
{
    if (m_fixedValueSize) {
        throw new Exception("can't change size of fixed sized property",
                            __FILE__, __LINE__, __FUNCTION__ );
    }
    if (m_values[index] != NULL) {
        m_values[index] = (uint8_t*)MP4Realloc(m_values[index], valueSize);
    }
    m_valueSizes[index] = valueSize;
}

void MP4BytesProperty::SetFixedSize(uint32_t fixedSize)
{
    m_fixedValueSize = 0;
    for (uint32_t i = 0; i < GetCount(); i++) {
        SetValueSize(fixedSize, i);
    }
    m_fixedValueSize = fixedSize;
}

void MP4BytesProperty::Read(MP4File& file, uint32_t index)
{
    if (m_implicit) {
        return;
    }
    MP4Free(m_values[index]);
    m_values[index] = (uint8_t*)MP4Malloc(m_valueSizes[index]);
    file.ReadBytes(m_values[index], m_valueSizes[index]);
}

void MP4BytesProperty::Write(MP4File& file, uint32_t index)
{
    if (m_implicit) {
        return;
    }
    file.WriteBytes(m_values[index], m_valueSizes[index]);
}

void MP4BytesProperty::Dump(uint8_t indent,
                            bool dumpImplicits, uint32_t index)
{
    if( m_implicit && !dumpImplicits )
        return;

    const uint32_t size  = m_valueSizes[index];
    const uint8_t* const value = m_values[index];

    if( size == 0 ) {
        log.dump(indent, MP4_LOG_VERBOSE2, "\"%s\": %s = <%u bytes>",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, size );
        return;
    }

    if( size <= 16 ) {
        ostringstream oss;
        ostringstream text;

        oss << "  ";
        for( uint32_t i = 0; i < size; i++ ) {
            if( i )
                oss << ' ';
            oss << std::hex << std::setw(2) << std::setfill('0') << right
                << static_cast<uint32_t>(value[i]);
            text << (isprint( static_cast<int>(value[i]) ) ? static_cast<char>(value[i]) : '.');
        }

        oss << "  |" << text.str() << "|";

        log.dump(indent, MP4_LOG_VERBOSE2, "\"%s\": %s = <%u bytes>%s",
                 m_parentAtom.GetFile().GetFilename().c_str(),
                 m_name, size, oss.str().c_str() );
        return;
    }

    // specialization for ilst item data always show all bytes except for covr
    bool showall = false;
    MP4Atom* const datac = m_parentAtom.GetParentAtom(); // data container
    MP4Atom* const datacc = datac->GetParentAtom();
    if( datacc &&
        ATOMID( datacc->GetType() ) == ATOMID( "ilst" ) &&
        ATOMID( datac->GetType() ) != ATOMID( "covr" ) )
    {
        showall = true;
    }

    uint32_t adjsize;
    bool supressed;

    if( showall ||
        size < 128 || log.verbosity >= MP4_LOG_VERBOSE2 )
    {
        adjsize = size;
        supressed = false;
    }
    else {
        adjsize = 128;
        supressed = true;
    }

    ostringstream oss;
    ostringstream text;

    log.dump(indent, MP4_LOG_VERBOSE2, "\"%s\": %s = <%u bytes>",
             m_parentAtom.GetFile().GetFilename().c_str(),
             m_name, size );
    log.hexDump(indent, MP4_LOG_VERBOSE2, value, adjsize, "\"%s\": %s",
                m_parentAtom.GetFile().GetFilename().c_str(),
                m_name);

    if( supressed ) {
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": <remaining bytes supressed>",
                 m_parentAtom.GetFile().GetFilename().c_str() );
    }
}

// MP4TableProperty

MP4TableProperty::MP4TableProperty(MP4Atom& parentAtom, const char* name, MP4IntegerProperty* pCountProperty)
        : MP4Property(parentAtom, name)
{
    m_pCountProperty = pCountProperty;
    m_pCountProperty->SetReadOnly();
}

MP4TableProperty::~MP4TableProperty()
{
    for (uint32_t i = 0; i < m_pProperties.Size(); i++) {
        delete m_pProperties[i];
    }
}

void MP4TableProperty::AddProperty(MP4Property* pProperty)
{
    ASSERT(pProperty);
    ASSERT(pProperty->GetType() != TableProperty);
    ASSERT(pProperty->GetType() != DescriptorProperty);
    m_pProperties.Add(pProperty);
    pProperty->SetCount(0);
}

bool MP4TableProperty::FindProperty(const char *name,
                                    MP4Property** ppProperty, uint32_t* pIndex)
{
    ASSERT(m_name);

    // check if first component of name matches ourselves
    if (!MP4NameFirstMatches(m_name, name)) {
        return false;
    }

    // check if the specified table entry exists
    uint32_t index;
    bool haveIndex = MP4NameFirstIndex(name, &index);
    if (haveIndex) {
        if (index >= GetCount()) {
            return false;
        }
        if (pIndex) {
            *pIndex = index;
        }
    }
    
    log.verbose1f("\"%s\": FindProperty: matched %s", 
                  m_parentAtom.GetFile().GetFilename().c_str(), name);

    // get name of table property
    const char *tablePropName = MP4NameAfterFirst(name);
    if (tablePropName == NULL) {
        if (!haveIndex) {
            *ppProperty = this;
            return true;
        }
        return false;
    }

    // check if this table property exists
    return FindContainedProperty(tablePropName, ppProperty, pIndex);
}

bool MP4TableProperty::FindContainedProperty(const char *name,
        MP4Property** ppProperty, uint32_t* pIndex)
{
    uint32_t numProperties = m_pProperties.Size();

    for (uint32_t i = 0; i < numProperties; i++) {
        if (m_pProperties[i]->FindProperty(name, ppProperty, pIndex)) {
            return true;
        }
    }
    return false;
}

void MP4TableProperty::Read(MP4File& file, uint32_t index)
{
    ASSERT(index == 0);

    if (m_implicit) {
        return;
    }

    uint32_t numProperties = m_pProperties.Size();

    if (numProperties == 0) {
        WARNING(numProperties == 0);
        return;
    }

    uint32_t numEntries = GetCount();

    /* for each property set size */
    for (uint32_t j = 0; j < numProperties; j++) {
        m_pProperties[j]->SetCount(numEntries);
    }

    for (uint32_t i = 0; i < numEntries; i++) {
        ReadEntry(file, i);
    }
}

void MP4TableProperty::ReadEntry(MP4File& file, uint32_t index)
{
    for (uint32_t j = 0; j < m_pProperties.Size(); j++) {
        m_pProperties[j]->Read(file, index);
    }
}

void MP4TableProperty::Write(MP4File& file, uint32_t index)
{
    ASSERT(index == 0);

    if (m_implicit) {
        return;
    }

    uint32_t numProperties = m_pProperties.Size();

    if (numProperties == 0) {
        WARNING(numProperties == 0);
        return;
    }

    uint32_t numEntries = GetCount();

    if (m_pProperties[0]->GetCount() != numEntries) {
        log.errorf("%s: \"%s\": %s %s \"%s\"table entries %u doesn't match count %u",
                   __FUNCTION__, m_parentAtom.GetFile().GetFilename().c_str(),
                   GetParentAtom().GetType(),
                   GetName(), m_pProperties[0]->GetName(),
                   m_pProperties[0]->GetCount(), numEntries);

        ASSERT(m_pProperties[0]->GetCount() == numEntries);
    }

    for (uint32_t i = 0; i < numEntries; i++) {
        WriteEntry(file, i);
    }
}

void MP4TableProperty::WriteEntry(MP4File& file, uint32_t index)
{
    for (uint32_t j = 0; j < m_pProperties.Size(); j++) {
        m_pProperties[j]->Write(file, index);
    }
}

void MP4TableProperty::Dump(uint8_t indent,
                            bool dumpImplicits, uint32_t index)
{
    ASSERT(index == 0);

    // implicit tables just can't be dumped
    if (m_implicit) {
        return;
    }

    uint32_t numProperties = m_pProperties.Size();

    if (numProperties == 0) {
        WARNING(numProperties == 0);
        return;
    }

    uint32_t numEntries = GetCount();

    for (uint32_t i = 0; i < numEntries; i++) {
        for (uint32_t j = 0; j < numProperties; j++) {
            m_pProperties[j]->Dump(indent + 1, dumpImplicits, i);
        }
    }
}

// MP4DescriptorProperty

MP4DescriptorProperty::MP4DescriptorProperty(MP4Atom& parentAtom, const char* name,
        uint8_t tagsStart, uint8_t tagsEnd, bool mandatory, bool onlyOne)
        : MP4Property(parentAtom, name)
{
    SetTags(tagsStart, tagsEnd);
    m_sizeLimit = 0;
    m_mandatory = mandatory;
    m_onlyOne = onlyOne;
}

MP4DescriptorProperty::~MP4DescriptorProperty()
{
    for (uint32_t i = 0; i < m_pDescriptors.Size(); i++) {
        delete m_pDescriptors[i];
    }
}

MP4Descriptor* MP4DescriptorProperty::AddDescriptor(uint8_t tag)
{
    // check that tag is in expected range
    ASSERT(tag >= m_tagsStart && tag <= m_tagsEnd);

    MP4Descriptor* pDescriptor = CreateDescriptor(m_parentAtom, tag);
    ASSERT(pDescriptor);

    m_pDescriptors.Add(pDescriptor);

    return pDescriptor;
}

void MP4DescriptorProperty::DeleteDescriptor(uint32_t index)
{
    delete m_pDescriptors[index];
    m_pDescriptors.Delete(index);
}

void MP4DescriptorProperty::Generate()
{
    // generate a default descriptor
    // if it is mandatory, and single
    if (m_mandatory && m_onlyOne) {
        MP4Descriptor* pDescriptor =
            AddDescriptor(m_tagsStart);
        pDescriptor->Generate();
    }
}

bool MP4DescriptorProperty::FindProperty(const char *name,
        MP4Property** ppProperty, uint32_t* pIndex)
{
    // we're unnamed, so just check contained properties
    if (m_name == NULL || !strcmp(m_name, "")) {
        return FindContainedProperty(name, ppProperty, pIndex);
    }

    // check if first component of name matches ourselves
    if (!MP4NameFirstMatches(m_name, name)) {
        return false;
    }

    // check if the specific descriptor entry exists
    uint32_t descrIndex;
    bool haveDescrIndex = MP4NameFirstIndex(name, &descrIndex);

    if (haveDescrIndex && descrIndex >= GetCount()) {
        return false;
    }

    log.verbose1f("\"%s\": matched %s",
                  m_parentAtom.GetFile().GetFilename().c_str(),
                  name);

    // get name of descriptor property
    name = MP4NameAfterFirst(name);
    if (name == NULL) {
        if (!haveDescrIndex) {
            *ppProperty = this;
            return true;
        }
        return false;
    }

    /* check rest of name */
    if (haveDescrIndex) {
        return m_pDescriptors[descrIndex]->FindProperty(name,
                ppProperty, pIndex);
    } else {
        return FindContainedProperty(name, ppProperty, pIndex);
    }
}

bool MP4DescriptorProperty::FindContainedProperty(const char *name,
        MP4Property** ppProperty, uint32_t* pIndex)
{
    for (uint32_t i = 0; i < m_pDescriptors.Size(); i++) {
        if (m_pDescriptors[i]->FindProperty(name, ppProperty, pIndex)) {
            return true;
        }
    }
    return false;
}

void MP4DescriptorProperty::Read(MP4File& file, uint32_t index)
{
    ASSERT(index == 0);

    if (m_implicit) {
        return;
    }

    uint64_t start = file.GetPosition();

    while (true) {
        // enforce size limitation
        if (m_sizeLimit && file.GetPosition() >= start + m_sizeLimit) {
            break;
        }

        uint8_t tag;
        try {
            file.PeekBytes(&tag, 1);
        }
        catch (Exception* x) {
            if (file.GetPosition() >= file.GetSize()) {
                // EOF
                delete x;
                break;
            }
            throw x;
        }

        // check if tag is in desired range
        if (tag < m_tagsStart || tag > m_tagsEnd) {
            break;
        }

        MP4Descriptor* pDescriptor =
            AddDescriptor(tag);

        pDescriptor->Read(file);
    }

    // warnings
    if (m_mandatory && m_pDescriptors.Size() == 0) {
        log.warningf("%s: \"%s\": Mandatory descriptor 0x%02x missing",
                     __FUNCTION__, GetParentAtom().GetFile().GetFilename().c_str(), m_tagsStart);
    } else if (m_onlyOne && m_pDescriptors.Size() > 1) {
        log.warningf("%s: \"%s\": Descriptor 0x%02x has more than one instance",
                     __FUNCTION__, GetParentAtom().GetFile().GetFilename().c_str(), m_tagsStart);
    }
}

void MP4DescriptorProperty::Write(MP4File& file, uint32_t index)
{
    ASSERT(index == 0);

    if (m_implicit) {
        return;
    }

    for (uint32_t i = 0; i < m_pDescriptors.Size(); i++) {
        m_pDescriptors[i]->Write(file);
    }
}

void MP4DescriptorProperty::Dump(uint8_t indent,
                                 bool dumpImplicits, uint32_t index)
{
    ASSERT(index == 0);

    if (m_implicit && !dumpImplicits) {
        return;
    }

    if (m_name) {
        if (index != 0)
            log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s[%u]",
                     m_parentAtom.GetFile().GetFilename().c_str(),
                     m_name, index);
        else
            log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s",
                     m_parentAtom.GetFile().GetFilename().c_str(),
                     m_name);
        indent++;
    }

    for (uint32_t i = 0; i < m_pDescriptors.Size(); i++) {
        m_pDescriptors[i]->Dump(indent, dumpImplicits);
    }
}

///////////////////////////////////////////////////////////////////////////////

MP4LanguageCodeProperty::MP4LanguageCodeProperty( MP4Atom& parentAtom, const char* name, bmff::LanguageCode value )
    : MP4Property( parentAtom, name )
{
    SetValue( value );
}

MP4LanguageCodeProperty::MP4LanguageCodeProperty( MP4Atom& parentAtom, const char* name, const std::string& code )
    : MP4Property( parentAtom, name )
{
    SetValue( bmff::enumLanguageCode.toType( code ));
}

void
MP4LanguageCodeProperty::Dump( uint8_t indent, bool dumpImplicits, uint32_t index )
{
    uint16_t data = 0;

    std::string svalue;
    bmff::enumLanguageCode.toString( _value, svalue );
    if( svalue.length() == 3 ) {
        data = (((svalue[0] - 0x60) & 0x001f) << 10)
             | (((svalue[1] - 0x60) & 0x001f) <<  5)
             | (((svalue[2] - 0x60) & 0x001f)      );
    }

    log.dump(indent, MP4_LOG_VERBOSE2, "\"%s\": %s = %s (0x%04x)",
             m_parentAtom.GetFile().GetFilename().c_str(),
             m_name, bmff::enumLanguageCode.toString( _value, true ).c_str(), data );
}

uint32_t
MP4LanguageCodeProperty::GetCount()
{
    return 1;
}

MP4PropertyType
MP4LanguageCodeProperty::GetType()
{
    return LanguageCodeProperty;
}

bmff::LanguageCode
MP4LanguageCodeProperty::GetValue()
{
    return _value;
}

void
MP4LanguageCodeProperty::Read( MP4File& file, uint32_t index )
{
    uint16_t data = file.ReadBits( 16 );

    char code[3];
    code[0] = ((data & 0x7c00) >> 10) + 0x60;
    code[1] = ((data & 0x03e0) >>  5) + 0x60;
    code[2] = ((data & 0x001f)      ) + 0x60;

    SetValue( bmff::enumLanguageCode.toType( std::string( code, sizeof(code) )));
}

void
MP4LanguageCodeProperty::SetCount( uint32_t count )
{
    // do nothing; count is always 1
}

void
MP4LanguageCodeProperty::SetValue( bmff::LanguageCode value )
{
    _value = value;
}

void
MP4LanguageCodeProperty::Write( MP4File& file, uint32_t index )
{
    uint16_t data = 0;

    std::string svalue;
    bmff::enumLanguageCode.toString( _value, svalue );
    if( svalue.length() == 3 ) {
        data = (((svalue[0] - 0x60) & 0x001f) << 10)
             | (((svalue[1] - 0x60) & 0x001f) <<  5)
             | (((svalue[2] - 0x60) & 0x001f)      );
    }

    file.WriteBits( data, 16 );
}

///////////////////////////////////////////////////////////////////////////////

MP4BasicTypeProperty::MP4BasicTypeProperty( MP4Atom& parentAtom, const char* name, itmf::BasicType type )
    : MP4Property( parentAtom, name )
{
    SetValue( type );
}

void
MP4BasicTypeProperty::Dump( uint8_t indent, bool dumpImplicits, uint32_t index )
{
    log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": %s = %s (0x%02x)",
             m_parentAtom.GetFile().GetFilename().c_str(), m_name,
             itmf::enumBasicType.toString( _value, true ).c_str(), _value );
}

uint32_t
MP4BasicTypeProperty::GetCount()
{
    return 1;
}

MP4PropertyType
MP4BasicTypeProperty::GetType()
{
    return BasicTypeProperty;
}

itmf::BasicType
MP4BasicTypeProperty::GetValue()
{
    return _value;
}

void
MP4BasicTypeProperty::Read( MP4File& file, uint32_t index )
{
    SetValue( static_cast<itmf::BasicType>( file.ReadBits( 8 )));
}

void
MP4BasicTypeProperty::SetCount( uint32_t count )
{
    // do nothing; count is always 1
}

void
MP4BasicTypeProperty::SetValue( itmf::BasicType value )
{
    _value = value;
}

void
MP4BasicTypeProperty::Write( MP4File& file, uint32_t index )
{
    file.WriteBits( _value, 8 );
}

///////////////////////////////////////////////////////////////////////////////

}} // namespace mp4v2::impl
