// Copyright 2019 The ebml-go authors.
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ebml

import (
	"bytes"
)

type elementDef struct {
	b   []byte
	t   DataType
	top bool
}
type elementTable map[ElementType]elementDef

var table = elementTable{
	ElementChapters:                    elementDef{[]byte{0x10, 0x43, 0xA7, 0x70}, DataTypeMaster, true},
	ElementSeekHead:                    elementDef{[]byte{0x11, 0x4D, 0x9B, 0x74}, DataTypeMaster, true},
	ElementTags:                        elementDef{[]byte{0x12, 0x54, 0xC3, 0x67}, DataTypeMaster, true},
	ElementInfo:                        elementDef{[]byte{0x15, 0x49, 0xA9, 0x66}, DataTypeMaster, true},
	ElementTracks:                      elementDef{[]byte{0x16, 0x54, 0xAE, 0x6B}, DataTypeMaster, true},
	ElementSegment:                     elementDef{[]byte{0x18, 0x53, 0x80, 0x67}, DataTypeMaster, false},
	ElementAttachments:                 elementDef{[]byte{0x19, 0x41, 0xA4, 0x69}, DataTypeMaster, true},
	ElementEBML:                        elementDef{[]byte{0x1A, 0x45, 0xDF, 0xA3}, DataTypeMaster, false},
	ElementCues:                        elementDef{[]byte{0x1C, 0x53, 0xBB, 0x6B}, DataTypeMaster, true},
	ElementCluster:                     elementDef{[]byte{0x1F, 0x43, 0xB6, 0x75}, DataTypeMaster, true},
	ElementLanguage:                    elementDef{[]byte{0x22, 0xB5, 0x9C}, DataTypeString, false},
	ElementLanguageIETF:                elementDef{[]byte{0x22, 0xB5, 0x9D}, DataTypeString, false},
	ElementTrackTimestampScale:         elementDef{[]byte{0x23, 0x31, 0x4F}, DataTypeFloat, false},
	ElementDefaultDecodedFieldDuration: elementDef{[]byte{0x23, 0x4E, 0x7A}, DataTypeUInt, false},
	ElementDefaultDuration:             elementDef{[]byte{0x23, 0xE3, 0x83}, DataTypeUInt, false},
	ElementCodecName:                   elementDef{[]byte{0x25, 0x86, 0x88}, DataTypeString, false},
	ElementTimecodeScale:               elementDef{[]byte{0x2A, 0xD7, 0xB1}, DataTypeUInt, false},
	ElementColourSpace:                 elementDef{[]byte{0x2E, 0xB5, 0x24}, DataTypeBinary, false},
	ElementPrevFilename:                elementDef{[]byte{0x3C, 0x83, 0xAB}, DataTypeString, false},
	ElementPrevUID:                     elementDef{[]byte{0x3C, 0xB9, 0x23}, DataTypeBinary, false},
	ElementNextFilename:                elementDef{[]byte{0x3E, 0x83, 0xBB}, DataTypeString, false},
	ElementNextUID:                     elementDef{[]byte{0x3E, 0xB9, 0x23}, DataTypeBinary, false},
	ElementBlockAddIDName:              elementDef{[]byte{0x41, 0xA4}, DataTypeString, false},
	ElementBlockAdditionMapping:        elementDef{[]byte{0x41, 0xE4}, DataTypeMaster, false},
	ElementBlockAddIDType:              elementDef{[]byte{0x41, 0xE7}, DataTypeUInt, false},
	ElementBlockAddIDExtraData:         elementDef{[]byte{0x41, 0xED}, DataTypeBinary, false},
	ElementBlockAddIDValue:             elementDef{[]byte{0x41, 0xF0}, DataTypeUInt, false},
	ElementContentCompAlgo:             elementDef{[]byte{0x42, 0x54}, DataTypeUInt, false},
	ElementContentCompSettings:         elementDef{[]byte{0x42, 0x55}, DataTypeBinary, false},
	ElementEBMLVersion:                 elementDef{[]byte{0x42, 0x86}, DataTypeUInt, false},
	ElementEBMLMaxIDLength:             elementDef{[]byte{0x42, 0xF2}, DataTypeUInt, false},
	ElementEBMLMaxSizeLength:           elementDef{[]byte{0x42, 0xF3}, DataTypeUInt, false},
	ElementEBMLReadVersion:             elementDef{[]byte{0x42, 0xF7}, DataTypeUInt, false},
	ElementEBMLDocType:                 elementDef{[]byte{0x42, 0x82}, DataTypeString, false},
	ElementEBMLDocTypeReadVersion:      elementDef{[]byte{0x42, 0x85}, DataTypeUInt, false},
	ElementEBMLDocTypeVersion:          elementDef{[]byte{0x42, 0x87}, DataTypeUInt, false},
	ElementChapLanguage:                elementDef{[]byte{0x43, 0x7C}, DataTypeString, false},
	ElementChapLanguageIETF:            elementDef{[]byte{0x43, 0x7D}, DataTypeString, false},
	ElementChapCountry:                 elementDef{[]byte{0x43, 0x7E}, DataTypeString, false},
	ElementSegmentFamily:               elementDef{[]byte{0x44, 0x44}, DataTypeBinary, false},
	ElementDateUTC:                     elementDef{[]byte{0x44, 0x61}, DataTypeDate, false},
	ElementTagLanguage:                 elementDef{[]byte{0x44, 0x7A}, DataTypeString, false},
	ElementTagLanguageIETF:             elementDef{[]byte{0x44, 0x7B}, DataTypeString, false},
	ElementTagDefault:                  elementDef{[]byte{0x44, 0x84}, DataTypeUInt, false},
	ElementTagBinary:                   elementDef{[]byte{0x44, 0x85}, DataTypeBinary, false},
	ElementTagString:                   elementDef{[]byte{0x44, 0x87}, DataTypeString, false},
	ElementDuration:                    elementDef{[]byte{0x44, 0x89}, DataTypeFloat, false},
	ElementChapProcessPrivate:          elementDef{[]byte{0x45, 0x0D}, DataTypeBinary, false},
	ElementChapterFlagEnabled:          elementDef{[]byte{0x45, 0x98}, DataTypeUInt, false},
	ElementTagName:                     elementDef{[]byte{0x45, 0xA3}, DataTypeString, false},
	ElementEditionEntry:                elementDef{[]byte{0x45, 0xB9}, DataTypeMaster, false},
	ElementEditionUID:                  elementDef{[]byte{0x45, 0xBC}, DataTypeUInt, false},
	ElementEditionFlagHidden:           elementDef{[]byte{0x45, 0xBD}, DataTypeUInt, false},
	ElementEditionFlagDefault:          elementDef{[]byte{0x45, 0xDB}, DataTypeUInt, false},
	ElementEditionFlagOrdered:          elementDef{[]byte{0x45, 0xDD}, DataTypeUInt, false},
	ElementFileData:                    elementDef{[]byte{0x46, 0x5C}, DataTypeBinary, false},
	ElementFileMimeType:                elementDef{[]byte{0x46, 0x60}, DataTypeString, false},
	ElementFileName:                    elementDef{[]byte{0x46, 0x6E}, DataTypeString, false},
	ElementFileDescription:             elementDef{[]byte{0x46, 0x7E}, DataTypeString, false},
	ElementFileUID:                     elementDef{[]byte{0x46, 0xAE}, DataTypeUInt, false},
	ElementContentEncAlgo:              elementDef{[]byte{0x47, 0xE1}, DataTypeUInt, false},
	ElementContentEncKeyID:             elementDef{[]byte{0x47, 0xE2}, DataTypeBinary, false},
	ElementContentSignature:            elementDef{[]byte{0x47, 0xE3}, DataTypeBinary, false},
	ElementContentSigKeyID:             elementDef{[]byte{0x47, 0xE4}, DataTypeBinary, false},
	ElementContentSigAlgo:              elementDef{[]byte{0x47, 0xE5}, DataTypeUInt, false},
	ElementContentSigHashAlgo:          elementDef{[]byte{0x47, 0xE6}, DataTypeUInt, false},
	ElementContentEncAESSettings:       elementDef{[]byte{0x47, 0xE7}, DataTypeMaster, false},
	ElementAESSettingsCipherMode:       elementDef{[]byte{0x47, 0xE8}, DataTypeUInt, false},
	ElementMuxingApp:                   elementDef{[]byte{0x4D, 0x80}, DataTypeString, false},
	ElementSeek:                        elementDef{[]byte{0x4D, 0xBB}, DataTypeMaster, false},
	ElementContentEncodingOrder:        elementDef{[]byte{0x50, 0x31}, DataTypeUInt, false},
	ElementContentEncodingScope:        elementDef{[]byte{0x50, 0x32}, DataTypeUInt, false},
	ElementContentEncodingType:         elementDef{[]byte{0x50, 0x33}, DataTypeUInt, false},
	ElementContentCompression:          elementDef{[]byte{0x50, 0x34}, DataTypeMaster, false},
	ElementContentEncryption:           elementDef{[]byte{0x50, 0x35}, DataTypeMaster, false},
	ElementSeekID:                      elementDef{[]byte{0x53, 0xAB}, DataTypeBinary, false},
	ElementSeekPosition:                elementDef{[]byte{0x53, 0xAC}, DataTypeUInt, false},
	ElementStereoMode:                  elementDef{[]byte{0x53, 0xB8}, DataTypeUInt, false},
	ElementAlphaMode:                   elementDef{[]byte{0x53, 0xC0}, DataTypeUInt, false},
	ElementName:                        elementDef{[]byte{0x53, 0x6E}, DataTypeString, false},
	ElementCueBlockNumber:              elementDef{[]byte{0x53, 0x78}, DataTypeUInt, false},
	ElementPixelCropBottom:             elementDef{[]byte{0x54, 0xAA}, DataTypeUInt, false},
	ElementDisplayWidth:                elementDef{[]byte{0x54, 0xB0}, DataTypeUInt, false},
	ElementDisplayUnit:                 elementDef{[]byte{0x54, 0xB2}, DataTypeUInt, false},
	ElementAspectRatioType:             elementDef{[]byte{0x54, 0xB3}, DataTypeUInt, false},
	ElementDisplayHeight:               elementDef{[]byte{0x54, 0xBA}, DataTypeUInt, false},
	ElementPixelCropTop:                elementDef{[]byte{0x54, 0xBB}, DataTypeUInt, false},
	ElementPixelCropLeft:               elementDef{[]byte{0x54, 0xCC}, DataTypeUInt, false},
	ElementPixelCropRight:              elementDef{[]byte{0x54, 0xDD}, DataTypeUInt, false},
	ElementFlagForced:                  elementDef{[]byte{0x55, 0xAA}, DataTypeUInt, false},
	ElementFlagHearingImpaired:         elementDef{[]byte{0x55, 0xAB}, DataTypeUInt, false},
	ElementFlagVisualImpaired:          elementDef{[]byte{0x55, 0xAC}, DataTypeUInt, false},
	ElementFlagTextDescriptions:        elementDef{[]byte{0x55, 0xAD}, DataTypeUInt, false},
	ElementFlagOriginal:                elementDef{[]byte{0x55, 0xAE}, DataTypeUInt, false},
	ElementFlagCommentary:              elementDef{[]byte{0x55, 0xAF}, DataTypeUInt, false},
	ElementColour:                      elementDef{[]byte{0x55, 0xB0}, DataTypeMaster, false},
	ElementMatrixCoefficients:          elementDef{[]byte{0x55, 0xB1}, DataTypeUInt, false},
	ElementBitsPerChannel:              elementDef{[]byte{0x55, 0xB2}, DataTypeUInt, false},
	ElementChromaSubsamplingHorz:       elementDef{[]byte{0x55, 0xB3}, DataTypeUInt, false},
	ElementChromaSubsamplingVert:       elementDef{[]byte{0x55, 0xB4}, DataTypeUInt, false},
	ElementCbSubsamplingHorz:           elementDef{[]byte{0x55, 0xB5}, DataTypeUInt, false},
	ElementCbSubsamplingVert:           elementDef{[]byte{0x55, 0xB6}, DataTypeUInt, false},
	ElementChromaSitingHorz:            elementDef{[]byte{0x55, 0xB7}, DataTypeUInt, false},
	ElementChromaSitingVert:            elementDef{[]byte{0x55, 0xB8}, DataTypeUInt, false},
	ElementRange:                       elementDef{[]byte{0x55, 0xB9}, DataTypeUInt, false},
	ElementTransferCharacteristics:     elementDef{[]byte{0x55, 0xBA}, DataTypeUInt, false},
	ElementPrimaries:                   elementDef{[]byte{0x55, 0xBB}, DataTypeUInt, false},
	ElementMaxCLL:                      elementDef{[]byte{0x55, 0xBC}, DataTypeUInt, false},
	ElementMaxFALL:                     elementDef{[]byte{0x55, 0xBD}, DataTypeUInt, false},
	ElementMasteringMetadata:           elementDef{[]byte{0x55, 0xD0}, DataTypeMaster, false},
	ElementPrimaryRChromaticityX:       elementDef{[]byte{0x55, 0xD1}, DataTypeFloat, false},
	ElementPrimaryRChromaticityY:       elementDef{[]byte{0x55, 0xD2}, DataTypeFloat, false},
	ElementPrimaryGChromaticityX:       elementDef{[]byte{0x55, 0xD3}, DataTypeFloat, false},
	ElementPrimaryGChromaticityY:       elementDef{[]byte{0x55, 0xD4}, DataTypeFloat, false},
	ElementPrimaryBChromaticityX:       elementDef{[]byte{0x55, 0xD5}, DataTypeFloat, false},
	ElementPrimaryBChromaticityY:       elementDef{[]byte{0x55, 0xD6}, DataTypeFloat, false},
	ElementWhitePointChromaticityX:     elementDef{[]byte{0x55, 0xD7}, DataTypeFloat, false},
	ElementWhitePointChromaticityY:     elementDef{[]byte{0x55, 0xD8}, DataTypeFloat, false},
	ElementLuminanceMax:                elementDef{[]byte{0x55, 0xD9}, DataTypeFloat, false},
	ElementLuminanceMin:                elementDef{[]byte{0x55, 0xDA}, DataTypeFloat, false},
	ElementMaxBlockAdditionID:          elementDef{[]byte{0x55, 0xEE}, DataTypeUInt, false},
	ElementChapterStringUID:            elementDef{[]byte{0x56, 0x54}, DataTypeString, false},
	ElementCodecDelay:                  elementDef{[]byte{0x56, 0xAA}, DataTypeUInt, false},
	ElementSeekPreRoll:                 elementDef{[]byte{0x56, 0xBB}, DataTypeUInt, false},
	ElementWritingApp:                  elementDef{[]byte{0x57, 0x41}, DataTypeString, false},
	ElementSilentTracks:                elementDef{[]byte{0x58, 0x54}, DataTypeMaster, false},
	ElementSilentTrackNumber:           elementDef{[]byte{0x58, 0xD7}, DataTypeUInt, false},
	ElementAttachedFile:                elementDef{[]byte{0x61, 0xA7}, DataTypeMaster, false},
	ElementContentEncoding:             elementDef{[]byte{0x62, 0x40}, DataTypeMaster, false},
	ElementBitDepth:                    elementDef{[]byte{0x62, 0x64}, DataTypeUInt, false},
	ElementCodecPrivate:                elementDef{[]byte{0x63, 0xA2}, DataTypeBinary, false},
	ElementTargets:                     elementDef{[]byte{0x63, 0xC0}, DataTypeMaster, false},
	ElementChapterPhysicalEquiv:        elementDef{[]byte{0x63, 0xC3}, DataTypeUInt, false},
	ElementTagChapterUID:               elementDef{[]byte{0x63, 0xC4}, DataTypeUInt, false},
	ElementTagTrackUID:                 elementDef{[]byte{0x63, 0xC5}, DataTypeUInt, false},
	ElementTagAttachmentUID:            elementDef{[]byte{0x63, 0xC6}, DataTypeUInt, false},
	ElementTagEditionUID:               elementDef{[]byte{0x63, 0xC9}, DataTypeUInt, false},
	ElementTargetType:                  elementDef{[]byte{0x63, 0xCA}, DataTypeString, false},
	ElementTrackTranslate:              elementDef{[]byte{0x66, 0x24}, DataTypeMaster, false},
	ElementTrackTranslateTrackID:       elementDef{[]byte{0x66, 0xA5}, DataTypeBinary, false},
	ElementTrackTranslateCodec:         elementDef{[]byte{0x66, 0xBF}, DataTypeUInt, false},
	ElementTrackTranslateEditionUID:    elementDef{[]byte{0x66, 0xFC}, DataTypeUInt, false},
	ElementSimpleTag:                   elementDef{[]byte{0x67, 0xC8}, DataTypeMaster, false},
	ElementTargetTypeValue:             elementDef{[]byte{0x68, 0xCA}, DataTypeUInt, false},
	ElementChapProcessCommand:          elementDef{[]byte{0x69, 0x11}, DataTypeMaster, false},
	ElementChapProcessTime:             elementDef{[]byte{0x69, 0x22}, DataTypeUInt, false},
	ElementChapterTranslate:            elementDef{[]byte{0x69, 0x24}, DataTypeMaster, false},
	ElementChapProcessData:             elementDef{[]byte{0x69, 0x33}, DataTypeBinary, false},
	ElementChapProcess:                 elementDef{[]byte{0x69, 0x44}, DataTypeMaster, false},
	ElementChapProcessCodecID:          elementDef{[]byte{0x69, 0x55}, DataTypeUInt, false},
	ElementChapterTranslateID:          elementDef{[]byte{0x69, 0xA5}, DataTypeBinary, false},
	ElementChapterTranslateCodec:       elementDef{[]byte{0x69, 0xBF}, DataTypeUInt, false},
	ElementChapterTranslateEditionUID:  elementDef{[]byte{0x69, 0xFC}, DataTypeUInt, false},
	ElementContentEncodings:            elementDef{[]byte{0x6D, 0x80}, DataTypeMaster, false},
	ElementMinCache:                    elementDef{[]byte{0x6D, 0xE7}, DataTypeUInt, false},
	ElementMaxCache:                    elementDef{[]byte{0x6D, 0xF8}, DataTypeUInt, false},
	ElementChapterSegmentUID:           elementDef{[]byte{0x6E, 0x67}, DataTypeBinary, false},
	ElementChapterSegmentEditionUID:    elementDef{[]byte{0x6E, 0xBC}, DataTypeUInt, false},
	ElementTrackOverlay:                elementDef{[]byte{0x6F, 0xAB}, DataTypeUInt, false},
	ElementTag:                         elementDef{[]byte{0x73, 0x73}, DataTypeMaster, false},
	ElementSegmentFilename:             elementDef{[]byte{0x73, 0x84}, DataTypeString, false},
	ElementSegmentUID:                  elementDef{[]byte{0x73, 0xA4}, DataTypeBinary, false},
	ElementChapterUID:                  elementDef{[]byte{0x73, 0xC4}, DataTypeUInt, false},
	ElementTrackUID:                    elementDef{[]byte{0x73, 0xC5}, DataTypeUInt, false},
	ElementAttachmentLink:              elementDef{[]byte{0x74, 0x46}, DataTypeUInt, false},
	ElementBlockAdditions:              elementDef{[]byte{0x75, 0xA1}, DataTypeMaster, false},
	ElementDiscardPadding:              elementDef{[]byte{0x75, 0xA2}, DataTypeInt, false},
	ElementProjection:                  elementDef{[]byte{0x76, 0x70}, DataTypeMaster, false},
	ElementProjectionType:              elementDef{[]byte{0x76, 0x71}, DataTypeUInt, false},
	ElementProjectionPrivate:           elementDef{[]byte{0x76, 0x72}, DataTypeBinary, false},
	ElementProjectionPoseYaw:           elementDef{[]byte{0x76, 0x73}, DataTypeFloat, false},
	ElementProjectionPosePitch:         elementDef{[]byte{0x76, 0x74}, DataTypeFloat, false},
	ElementProjectionPoseRoll:          elementDef{[]byte{0x76, 0x75}, DataTypeFloat, false},
	ElementOutputSamplingFrequency:     elementDef{[]byte{0x78, 0xB5}, DataTypeFloat, false},
	ElementTitle:                       elementDef{[]byte{0x7B, 0xA9}, DataTypeString, false},
	ElementChapterDisplay:              elementDef{[]byte{0x80}, DataTypeMaster, false},
	ElementTrackType:                   elementDef{[]byte{0x83}, DataTypeUInt, false},
	ElementChapString:                  elementDef{[]byte{0x85}, DataTypeString, false},
	ElementCodecID:                     elementDef{[]byte{0x86}, DataTypeString, false},
	ElementFlagDefault:                 elementDef{[]byte{0x88}, DataTypeUInt, false},
	ElementChapterTrackUID:             elementDef{[]byte{0x89}, DataTypeUInt, false},
	ElementSlices:                      elementDef{[]byte{0x8E}, DataTypeMaster, false},
	ElementChapterTrack:                elementDef{[]byte{0x8F}, DataTypeMaster, false},
	ElementChapterTimeStart:            elementDef{[]byte{0x91}, DataTypeUInt, false},
	ElementChapterTimeEnd:              elementDef{[]byte{0x92}, DataTypeUInt, false},
	ElementCueRefTime:                  elementDef{[]byte{0x96}, DataTypeUInt, false},
	ElementChapterFlagHidden:           elementDef{[]byte{0x98}, DataTypeUInt, false},
	ElementFlagInterlaced:              elementDef{[]byte{0x9A}, DataTypeUInt, false},
	ElementBlockDuration:               elementDef{[]byte{0x9B}, DataTypeUInt, false},
	ElementFlagLacing:                  elementDef{[]byte{0x9C}, DataTypeUInt, false},
	ElementFieldOrder:                  elementDef{[]byte{0x9D}, DataTypeUInt, false},
	ElementChannels:                    elementDef{[]byte{0x9F}, DataTypeUInt, false},
	ElementBlockGroup:                  elementDef{[]byte{0xA0}, DataTypeMaster, false},
	ElementBlock:                       elementDef{[]byte{0xA1}, DataTypeBlock, false},
	ElementSimpleBlock:                 elementDef{[]byte{0xA3}, DataTypeBlock, false},
	ElementCodecState:                  elementDef{[]byte{0xA4}, DataTypeBinary, false},
	ElementBlockAdditional:             elementDef{[]byte{0xA5}, DataTypeBinary, false},
	ElementBlockMore:                   elementDef{[]byte{0xA6}, DataTypeMaster, false},
	ElementPosition:                    elementDef{[]byte{0xA7}, DataTypeUInt, false},
	ElementCodecDecodeAll:              elementDef{[]byte{0xAA}, DataTypeUInt, false},
	ElementPrevSize:                    elementDef{[]byte{0xAB}, DataTypeUInt, false},
	ElementTrackEntry:                  elementDef{[]byte{0xAE}, DataTypeMaster, false},
	ElementPixelWidth:                  elementDef{[]byte{0xB0}, DataTypeUInt, false},
	ElementCueDuration:                 elementDef{[]byte{0xB2}, DataTypeUInt, false},
	ElementCueTime:                     elementDef{[]byte{0xB3}, DataTypeUInt, false},
	ElementSamplingFrequency:           elementDef{[]byte{0xB5}, DataTypeFloat, false},
	ElementChapterAtom:                 elementDef{[]byte{0xB6}, DataTypeMaster, false},
	ElementCueTrackPositions:           elementDef{[]byte{0xB7}, DataTypeMaster, false},
	ElementFlagEnabled:                 elementDef{[]byte{0xB9}, DataTypeUInt, false},
	ElementPixelHeight:                 elementDef{[]byte{0xBA}, DataTypeUInt, false},
	ElementCuePoint:                    elementDef{[]byte{0xBB}, DataTypeMaster, false},
	ElementCRC32:                       elementDef{[]byte{0xBF}, DataTypeBinary, false},
	ElementLaceNumber:                  elementDef{[]byte{0xCC}, DataTypeUInt, false},
	ElementTrackNumber:                 elementDef{[]byte{0xD7}, DataTypeUInt, false},
	ElementCueReference:                elementDef{[]byte{0xDB}, DataTypeMaster, false},
	ElementVideo:                       elementDef{[]byte{0xE0}, DataTypeMaster, false},
	ElementAudio:                       elementDef{[]byte{0xE1}, DataTypeMaster, false},
	ElementTrackOperation:              elementDef{[]byte{0xE2}, DataTypeMaster, false},
	ElementTrackCombinePlanes:          elementDef{[]byte{0xE3}, DataTypeMaster, false},
	ElementTrackPlane:                  elementDef{[]byte{0xE4}, DataTypeMaster, false},
	ElementTrackPlaneUID:               elementDef{[]byte{0xE5}, DataTypeUInt, false},
	ElementTrackPlaneType:              elementDef{[]byte{0xE6}, DataTypeUInt, false},
	ElementTimecode:                    elementDef{[]byte{0xE7}, DataTypeUInt, false},
	ElementTimeSlice:                   elementDef{[]byte{0xE8}, DataTypeMaster, false},
	ElementTrackJoinBlocks:             elementDef{[]byte{0xE9}, DataTypeMaster, false},
	ElementCueCodecState:               elementDef{[]byte{0xEA}, DataTypeUInt, false},
	ElementVoid:                        elementDef{[]byte{0xEC}, DataTypeBinary, false},
	ElementTrackJoinUID:                elementDef{[]byte{0xED}, DataTypeUInt, false},
	ElementBlockAddID:                  elementDef{[]byte{0xEE}, DataTypeUInt, false},
	ElementCueRelativePosition:         elementDef{[]byte{0xF0}, DataTypeUInt, false},
	ElementCueClusterPosition:          elementDef{[]byte{0xF1}, DataTypeUInt, false},
	ElementCueTrack:                    elementDef{[]byte{0xF7}, DataTypeUInt, false},
	ElementReferencePriority:           elementDef{[]byte{0xFA}, DataTypeUInt, false},
	ElementReferenceBlock:              elementDef{[]byte{0xFB}, DataTypeInt, false},
}

type elementRevTable map[uint32]element
type element struct {
	e   ElementType
	t   DataType
	top bool
}

var revTable elementRevTable

func init() {
	revTable = make(elementRevTable)
	initReverseLookupTable(revTable, table)
}

func initReverseLookupTable(revTb elementRevTable, tb elementTable) {
	vd := &valueDecoder{}
	for k, v := range tb {
		e, _, err := vd.readVUInt(bytes.NewBuffer(v.b))
		if err != nil {
			panic(err)
		}
		revTb[uint32(e)] = element{e: k, t: v.t, top: v.top}
	}
}
