/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre
 *			Copyright (c) Telecom ParisTech 2000-2012
 *					All rights reserved
 *
 *  This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC 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; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */


#include <gpac/internal/odf_dev.h>


GF_Err gf_odf_parse_command(GF_BitStream *bs, GF_ODCom **com, u32 *com_size)
{
	u32 val, size, sizeHeader;
	u8 tag;
	GF_Err err;
	GF_ODCom *newCom;
	if (!bs) return GF_BAD_PARAM;

	*com_size = 0;

	//tag
	tag = gf_bs_read_int(bs, 8);
	sizeHeader = 1;

	//size
	size = 0;
	do {
		val = gf_bs_read_int(bs, 8);
		sizeHeader++;
		size <<= 7;
		size |= val & 0x7F;
	} while ( val & 0x80 );
	*com_size = size;

	newCom = gf_odf_create_command(tag);
	if (! newCom) {
		*com = NULL;
		return GF_OUT_OF_MEM;
	}

	newCom->tag = tag;

	err = gf_odf_read_command(bs, newCom, *com_size);
	//little trick to handle lazy bitstreams that encode
	//SizeOfInstance on a fix number of bytes
	//This nb of bytes is added in Read methods
	*com_size += sizeHeader - gf_odf_size_field_size(*com_size);
	*com = newCom;
	if (err) {
		gf_odf_delete_command(newCom);
		*com = NULL;
	}
	return err;
}

#ifndef GPAC_MINIMAL_ODF

GF_ODCom *gf_odf_new_base_command()
{
	GF_BaseODCom *newCom = (GF_BaseODCom *) gf_malloc(sizeof(GF_BaseODCom));
	if (!newCom) return NULL;
	newCom->dataSize = 0;
	newCom->data = NULL;
	return (GF_ODCom *)newCom;
}
GF_Err gf_odf_del_base_command(GF_BaseODCom *bcRemove)
{
	if (! bcRemove) return GF_BAD_PARAM;
	if (bcRemove->data) gf_free(bcRemove->data);
	gf_free(bcRemove);
	return GF_OK;
}

GF_Err gf_odf_read_base_command(GF_BitStream *bs, GF_BaseODCom *bcRem, u32 gf_odf_size_command)
{
	if (! bcRem) return GF_BAD_PARAM;

	bcRem->dataSize = gf_odf_size_command;
	bcRem->data = (char *) gf_malloc(sizeof(char) * bcRem->dataSize);
	if (! bcRem->data) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, bcRem->data, bcRem->dataSize);
	return GF_OK;
}
GF_Err gf_odf_size_base_command(GF_BaseODCom *bcRem, u32 *outSize)
{
	if (!bcRem) return GF_BAD_PARAM;
	*outSize = bcRem->dataSize;
	return GF_OK;
}
GF_Err gf_odf_write_base_command(GF_BitStream *bs, GF_BaseODCom *bcRem)
{
	u32 size;
	GF_Err e;
	if (! bcRem) return GF_BAD_PARAM;

	e = gf_odf_size_base_command(bcRem, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, bcRem->tag, size);
	if (e) return e;
	gf_bs_write_data(bs, bcRem->data, bcRem->dataSize);
	return GF_OK;
}
#endif

GF_ODCom *gf_odf_new_od_remove()
{
	GF_ODRemove *newCom = (GF_ODRemove *) gf_malloc(sizeof(GF_ODRemove));
	if (!newCom) return NULL;
	newCom->NbODs = 0;
	newCom->OD_ID = NULL;
	newCom->tag = GF_ODF_OD_REMOVE_TAG;
	return (GF_ODCom *)newCom;
}
GF_Err gf_odf_del_od_remove(GF_ODRemove *ODRemove)
{
	if (! ODRemove) return GF_BAD_PARAM;
	if (ODRemove->OD_ID) gf_free(ODRemove->OD_ID);
	gf_free(ODRemove);
	return GF_OK;
}
GF_Err gf_odf_read_od_remove(GF_BitStream *bs, GF_ODRemove *odRem, u32 gf_odf_size_command)
{
	u32 i = 0, nbBits;
	if (! odRem) return GF_BAD_PARAM;

	odRem->NbODs = (u32 ) (gf_odf_size_command * 8) / 10;
	odRem->OD_ID = (u16 *) gf_malloc(sizeof(u16) * odRem->NbODs);
	if (! odRem->OD_ID) return GF_OUT_OF_MEM;

	for (i = 0; i < odRem->NbODs ; i++) {
		odRem->OD_ID[i] = gf_bs_read_int(bs, 10);
	}
	nbBits = odRem->NbODs * 10;
	//now we need to align !!!
	nbBits += gf_bs_align(bs);
	if (nbBits != (gf_odf_size_command * 8)) return GF_ODF_INVALID_COMMAND;
	return GF_OK;
}

GF_Err gf_odf_size_od_remove(GF_ODRemove *odRem, u32 *outSize)
{
	u32 size;
	if (!odRem) return GF_BAD_PARAM;

	size = 10 * odRem->NbODs;
	*outSize = size/8;
	if (*outSize * 8 != size) *outSize += 1;
	return GF_OK;
}

GF_Err gf_odf_write_od_remove(GF_BitStream *bs, GF_ODRemove *odRem)
{
	GF_Err e;
	u32 size, i;
	if (! odRem) return GF_BAD_PARAM;

	e = gf_odf_size_od_remove(odRem, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, odRem->tag, size);
	if (e) return e;

	for (i = 0; i < odRem->NbODs; i++) {
		gf_bs_write_int(bs, odRem->OD_ID[i], 10);
	}
	//OD commands are aligned
	gf_bs_align(bs);
	return GF_OK;
}



GF_ODCom *gf_odf_new_od_update()
{
	GF_ODUpdate *newCom = (GF_ODUpdate *) gf_malloc(sizeof(GF_ODUpdate));
	if (!newCom) return NULL;

	newCom->objectDescriptors = gf_list_new();
	if (! newCom->objectDescriptors) {
		gf_free(newCom);
		return NULL;
	}
	newCom->tag = GF_ODF_OD_UPDATE_TAG;
	return (GF_ODCom *)newCom;
}

GF_Err gf_odf_del_od_update(GF_ODUpdate *ODUpdate)
{
	GF_Err e;
	if (! ODUpdate) return GF_BAD_PARAM;
	while (gf_list_count(ODUpdate->objectDescriptors)) {
		GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(ODUpdate->objectDescriptors, 0);
		e = gf_odf_delete_descriptor(tmp);
		if (e) return e;
		e = gf_list_rem(ODUpdate->objectDescriptors, 0);
		if (e) return e;
	}
	gf_list_del(ODUpdate->objectDescriptors);
	gf_free(ODUpdate);
	return GF_OK;
}



GF_Err AddToODUpdate(GF_ODUpdate *odUp, GF_Descriptor *desc)
{
	if (! odUp) return GF_BAD_PARAM;
	if (! desc) return GF_OK;

	switch (desc->tag) {
	case GF_ODF_OD_TAG:
	case GF_ODF_IOD_TAG:
	case GF_ODF_ISOM_IOD_TAG:
	case GF_ODF_ISOM_OD_TAG:
		return gf_list_add(odUp->objectDescriptors, desc);

	default:
		gf_odf_delete_descriptor(desc);
		return GF_OK;
	}
}

GF_Err gf_odf_read_od_update(GF_BitStream *bs, GF_ODUpdate *odUp, u32 gf_odf_size_command)
{
	GF_Descriptor *tmp;
	GF_Err e = GF_OK;
	u32 tmpSize = 0, nbBytes = 0;
	if (! odUp) return GF_BAD_PARAM;

	while (nbBytes < gf_odf_size_command && gf_bs_available(bs)) {
		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
		if (e) return e;
		if (!tmpSize) break;
		e = AddToODUpdate(odUp, tmp);
		if (e) return e;
		nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	//OD commands are aligned
	gf_bs_align(bs);
	if (nbBytes != gf_odf_size_command) return GF_ODF_INVALID_COMMAND;
	return e;
}
GF_Err gf_odf_size_od_update(GF_ODUpdate *odUp, u32 *outSize)
{
	GF_Descriptor *tmp;
	u32 i, tmpSize;
	if (!odUp) return GF_BAD_PARAM;

	*outSize = 0;
	i=0;
	while ((tmp = (GF_Descriptor *)gf_list_enum(odUp->objectDescriptors, &i))) {
		gf_odf_size_descriptor(tmp, &tmpSize);
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	return GF_OK;
}
GF_Err gf_odf_write_od_update(GF_BitStream *bs, GF_ODUpdate *odUp)
{
	GF_Err e;
	GF_Descriptor *tmp;
	u32 size, i;
	if (! odUp) return GF_BAD_PARAM;

	e = gf_odf_size_od_update(odUp, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, odUp->tag, size);
	if (e) return e;

	i=0;
	while ((tmp = (GF_Descriptor *)gf_list_enum(odUp->objectDescriptors, &i))) {
		e = gf_odf_write_descriptor(bs, tmp);
		if (e) return e;
	}
	//OD commands are aligned
	gf_bs_align(bs);
	return GF_OK;
}


GF_ODCom *gf_odf_new_esd_update()
{
	GF_ESDUpdate *newCom = (GF_ESDUpdate *) gf_malloc(sizeof(GF_ESDUpdate));
	if (!newCom) return NULL;

	newCom->ESDescriptors = gf_list_new();
	if (! newCom->ESDescriptors) {
		gf_free(newCom);
		return NULL;
	}
	newCom->tag = GF_ODF_ESD_UPDATE_TAG;
	return (GF_ODCom *)newCom;
}

GF_Err gf_odf_del_esd_update(GF_ESDUpdate *ESDUpdate)
{
	GF_Err e;
	if (! ESDUpdate) return GF_BAD_PARAM;
	while (gf_list_count(ESDUpdate->ESDescriptors)) {
		GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(ESDUpdate->ESDescriptors, 0);
		e = gf_odf_delete_descriptor(tmp);
		if (e) return e;
		e = gf_list_rem(ESDUpdate->ESDescriptors, 0);
		if (e) return e;
	}
	gf_list_del(ESDUpdate->ESDescriptors);
	gf_free(ESDUpdate);
	return GF_OK;
}

GF_Err AddToESDUpdate(GF_ESDUpdate *esdUp, GF_Descriptor *desc)
{
	if (! esdUp) return GF_BAD_PARAM;
	if (!desc) return GF_OK;

	switch (desc->tag) {
	case GF_ODF_ESD_TAG:
	case GF_ODF_ESD_REF_TAG:
		return gf_list_add(esdUp->ESDescriptors, desc);

	default:
		gf_odf_delete_descriptor(desc);
		return GF_OK;
	}
}

GF_Err gf_odf_read_esd_update(GF_BitStream *bs, GF_ESDUpdate *esdUp, u32 gf_odf_size_command)
{
	GF_Descriptor *tmp;
	u32 tmpSize = 0, nbBits = 0;
	GF_Err e = GF_OK;
	if (! esdUp) return GF_BAD_PARAM;

	esdUp->ODID = gf_bs_read_int(bs, 10);
	nbBits += 10;
	//very tricky, we're at the bit level here...
	while (1) {
		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
		if (e) return e;
		e = AddToESDUpdate(esdUp, tmp);
		if (e) return e;
		nbBits += ( tmpSize + gf_odf_size_field_size(tmpSize) ) * 8;
		//our com is aligned, so nbBits is between (gf_odf_size_command-1)*8 and gf_odf_size_command*8
		if ( ( (nbBits >(gf_odf_size_command-1)*8) && (nbBits <= gf_odf_size_command * 8))
		        || (nbBits > gf_odf_size_command*8) ) {	//this one is a security break
			break;
		}
	}
	if (nbBits > gf_odf_size_command * 8) return GF_ODF_INVALID_COMMAND;
	//Align our bitstream
	nbBits += gf_bs_align(bs);
	if (nbBits != gf_odf_size_command *8) return GF_ODF_INVALID_COMMAND;
	return e;
}



GF_Err gf_odf_size_esd_update(GF_ESDUpdate *esdUp, u32 *outSize)
{
	u32 i, BitSize, tmpSize;
	GF_Descriptor *tmp;
	if (!esdUp) return GF_BAD_PARAM;

	*outSize = 0;
	BitSize = 10;
	i=0;
	while ((tmp = (GF_Descriptor *)gf_list_enum(esdUp->ESDescriptors, &i))) {
		gf_odf_size_descriptor(tmp, &tmpSize);
		BitSize += ( tmpSize + gf_odf_size_field_size(tmpSize) ) * 8;
	}
	while ((s32) BitSize > 0) {
		BitSize -= 8;
		*outSize += 1;
	}
	return GF_OK;
}
GF_Err gf_odf_write_esd_update(GF_BitStream *bs, GF_ESDUpdate *esdUp)
{
	GF_Descriptor *tmp;
	GF_Err e;
	u32 size, i;
	if (! esdUp) return GF_BAD_PARAM;

	e = gf_odf_size_esd_update(esdUp, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, esdUp->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, esdUp->ODID, 10);
	i=0;
	while ((tmp = (GF_Descriptor *)gf_list_enum(esdUp->ESDescriptors, &i))) {
		e = gf_odf_write_descriptor(bs, tmp);
		if (e) return e;
	}
	//OD commands are aligned
	gf_bs_align(bs);
	return GF_OK;
}


GF_ODCom *gf_odf_new_esd_remove()
{
	GF_ESDRemove *newCom = (GF_ESDRemove *) gf_malloc(sizeof(GF_ESDRemove));
	if (!newCom) return NULL;
	newCom->NbESDs = 0;
	newCom->ES_ID = NULL;
	newCom->tag = GF_ODF_ESD_REMOVE_TAG;
	return (GF_ODCom *)newCom;
}

GF_Err gf_odf_del_esd_remove(GF_ESDRemove *ESDRemove)
{
	if (! ESDRemove) return GF_BAD_PARAM;
	if (ESDRemove->ES_ID) gf_free(ESDRemove->ES_ID);
	gf_free(ESDRemove);
	return GF_OK;
}


GF_Err gf_odf_read_esd_remove(GF_BitStream *bs, GF_ESDRemove *esdRem, u32 gf_odf_size_command)
{
	u32 i = 0;
	if (! esdRem) return GF_BAD_PARAM;

	esdRem->ODID = gf_bs_read_int(bs, 10);
	/*aligned = */gf_bs_read_int(bs, 6);		//aligned

	//we have gf_odf_size_command - 2 bytes left, and this is our ES_ID[1...255]
	//this works because OD commands are aligned
	if (gf_odf_size_command < 2) return GF_ODF_INVALID_DESCRIPTOR;
	if (gf_odf_size_command == 2) {
		esdRem->NbESDs = 0;
		esdRem->ES_ID = NULL;
		return GF_OK;
	}
	esdRem->NbESDs = (gf_odf_size_command - 2) / 2;
	if (esdRem->NbESDs > gf_bs_available(bs) / sizeof(u16)) {
		return GF_NON_COMPLIANT_BITSTREAM;
	}

	esdRem->ES_ID = (u16 *) gf_malloc(sizeof(u16) * esdRem->NbESDs);
	if (! esdRem->ES_ID) return GF_OUT_OF_MEM;

	for (i = 0; i < esdRem->NbESDs ; i++) {
		esdRem->ES_ID[i] = gf_bs_read_int(bs, 16);
	}
	//OD commands are aligned (but we should already be aligned....
	/*nbBits = */gf_bs_align(bs);
	return GF_OK;
}

GF_Err gf_odf_size_esd_remove(GF_ESDRemove *esdRem, u32 *outSize)
{
	if (!esdRem) return GF_BAD_PARAM;
	*outSize = 2 + 2 * esdRem->NbESDs;
	return GF_OK;
}
GF_Err gf_odf_write_esd_remove(GF_BitStream *bs, GF_ESDRemove *esdRem)
{
	GF_Err e;
	u32 size, i;
	if (! esdRem) return GF_BAD_PARAM;

	e = gf_odf_size_esd_remove(esdRem, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, esdRem->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, esdRem->ODID, 10);
	gf_bs_write_int(bs, 0, 6);		//aligned
	for (i = 0; i < esdRem->NbESDs ; i++) {
		gf_bs_write_int(bs, esdRem->ES_ID[i], 16);
	}
	//OD commands are aligned (but we are already aligned....
	gf_bs_align(bs);
	return GF_OK;
}

#ifndef GPAC_MINIMAL_ODF

GF_ODCom *gf_odf_new_ipmp_remove()
{
	GF_IPMPRemove *newCom = (GF_IPMPRemove *) gf_malloc(sizeof(GF_IPMPRemove));
	if (!newCom) return NULL;
	newCom->IPMPDescID  =NULL;
	newCom->NbIPMPDs = 0;
	newCom->tag = GF_ODF_IPMP_REMOVE_TAG;
	return (GF_ODCom *)newCom;
}

GF_Err gf_odf_del_ipmp_remove(GF_IPMPRemove *IPMPDRemove)
{
	if (! IPMPDRemove) return GF_BAD_PARAM;
	if (IPMPDRemove->IPMPDescID) gf_free(IPMPDRemove->IPMPDescID);
	gf_free(IPMPDRemove);
	return GF_OK;
}

GF_Err gf_odf_read_ipmp_remove(GF_BitStream *bs, GF_IPMPRemove *ipmpRem, u32 gf_odf_size_command)
{
	u32 i;
	if (! ipmpRem) return GF_BAD_PARAM;

	//we have gf_odf_size_command bytes left, and this is our IPMPD_ID[1...255]
	//this works because OD commands are aligned
	if (!gf_odf_size_command) return GF_OK;

	ipmpRem->NbIPMPDs = gf_odf_size_command;
	ipmpRem->IPMPDescID = (u8 *) gf_malloc(sizeof(u8) * ipmpRem->NbIPMPDs);
	if (! ipmpRem->IPMPDescID) return GF_OUT_OF_MEM;

	for (i = 0; i < ipmpRem->NbIPMPDs; i++) {
		ipmpRem->IPMPDescID[i] = gf_bs_read_int(bs, 8);
	}
	//OD commands are aligned
	gf_bs_align(bs);
	return GF_OK;
}

GF_Err gf_odf_size_ipmp_remove(GF_IPMPRemove *ipmpRem, u32 *outSize)
{
	if (!ipmpRem) return GF_BAD_PARAM;

	*outSize = ipmpRem->NbIPMPDs;
	return GF_OK;
}
GF_Err gf_odf_write_ipmp_remove(GF_BitStream *bs, GF_IPMPRemove *ipmpRem)
{
	GF_Err e;
	u32 size, i;
	if (! ipmpRem) return GF_BAD_PARAM;

	e = gf_odf_size_ipmp_remove(ipmpRem, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ipmpRem->tag, size);
	if (e) return e;

	for (i = 0; i < ipmpRem->NbIPMPDs; i++) {
		gf_bs_write_int(bs, ipmpRem->IPMPDescID[i], 8);
	}
	//OD commands are aligned
	gf_bs_align(bs);
	return GF_OK;
}

GF_ODCom *gf_odf_new_ipmp_update()
{
	GF_IPMPUpdate *newCom = (GF_IPMPUpdate *) gf_malloc(sizeof(GF_IPMPUpdate));
	if (!newCom) return NULL;
	newCom->IPMPDescList = gf_list_new();
	if (! newCom->IPMPDescList) {
		gf_free(newCom);
		return NULL;
	}
	newCom->tag = GF_ODF_IPMP_UPDATE_TAG;
	return (GF_ODCom *)newCom;
}

GF_Err gf_odf_del_ipmp_update(GF_IPMPUpdate *IPMPDUpdate)
{
	GF_Err e;
	if (! IPMPDUpdate) return GF_BAD_PARAM;
	while (gf_list_count(IPMPDUpdate->IPMPDescList)) {
		GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(IPMPDUpdate->IPMPDescList, 0);
		e = gf_odf_delete_descriptor(tmp);
		if (e) return e;
		e = gf_list_rem(IPMPDUpdate->IPMPDescList, 0);
		if (e) return e;
	}
	gf_list_del(IPMPDUpdate->IPMPDescList);
	gf_free(IPMPDUpdate);
	return GF_OK;
}

GF_Err AddToIPMPDUpdate(GF_IPMPUpdate *ipmpUp, GF_Descriptor *desc)
{
	if (! ipmpUp) return GF_BAD_PARAM;
	if (!desc) return GF_OK;

	switch (desc->tag) {
	case GF_ODF_IPMP_TAG:
		return gf_list_add(ipmpUp->IPMPDescList, desc);
	default:
		gf_odf_delete_descriptor(desc);
		return GF_OK;
	}
}

GF_Err gf_odf_read_ipmp_update(GF_BitStream *bs, GF_IPMPUpdate *ipmpUp, u32 gf_odf_size_command)
{
	GF_Descriptor *tmp;
	u32 tmpSize = 0, nbBytes = 0;
	GF_Err e = GF_OK;
	if (! ipmpUp) return GF_BAD_PARAM;

	while (nbBytes < gf_odf_size_command) {
		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
		if (e) return e;
		e = AddToIPMPDUpdate(ipmpUp, tmp);
		if (e) return e;
		nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	//OD commands are aligned
	gf_bs_align(bs);
	if (nbBytes != gf_odf_size_command) return GF_ODF_INVALID_COMMAND;
	return e;
}


GF_Err gf_odf_size_ipmp_update(GF_IPMPUpdate *ipmpUp, u32 *outSize)
{
	GF_Descriptor *tmp;
	u32 i, tmpSize;
	if (!ipmpUp) return GF_BAD_PARAM;

	*outSize = 0;
	i=0;
	while ((tmp = (GF_Descriptor *)gf_list_enum(ipmpUp->IPMPDescList, &i))) {
		gf_odf_size_descriptor(tmp, &tmpSize);
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	return GF_OK;
}
GF_Err gf_odf_write_ipmp_update(GF_BitStream *bs, GF_IPMPUpdate *ipmpUp)
{
	GF_Err e;
	GF_Descriptor *tmp;
	u32 size, i;
	if (! ipmpUp) return GF_BAD_PARAM;

	e = gf_odf_size_ipmp_update(ipmpUp, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ipmpUp->tag, size);
	if (e) return e;

	i=0;
	while ((tmp = (GF_Descriptor *)gf_list_enum(ipmpUp->IPMPDescList, &i))) {
		e = gf_odf_write_descriptor(bs, tmp);
		if (e) return e;
	}
	//OD commands are aligned
	gf_bs_align(bs);
	return GF_OK;
}
#endif
