///////////////////////////////////////////////////////////////////////////////
//
//  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 MP4v2.
// 
//  The Initial Developer of the Original Code is Kona Blend.
//  Portions created by Kona Blend are Copyright (C) 2008.
//  All Rights Reserved.
//
//  Contributors:
//      Kona Blend, kona8lend@@gmail.com
//
///////////////////////////////////////////////////////////////////////////////

#include "libutil/impl.h"

namespace mp4v2 { namespace util {

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

TrackModifier::TrackModifier( MP4FileHandle file_, uint16_t trackIndex_ )
    : _track          ( refTrackAtom( *static_cast<MP4File*>(file_), trackIndex_ ))
    , _props          ( *this ) // must come after _track is initialized
    , _enabled        ( false )
    , _inMovie        ( false )
    , _inPreview      ( false )
    , _layer          ( 0 )
    , _alternateGroup ( 0 )
    , _volume         ( 1.0f )
    , _width          ( 0.0f )
    , _height         ( 0.0f )
    , _language       ( bmff::ILC_UND )
    , _handlerType    ( "" )
    , _handlerName    ( "" )
    , _userDataName   ( "" )
    , file            ( *static_cast<MP4File*>(file_) )
    , trackIndex      ( trackIndex_ )
    , trackId         ( MP4FindTrackId( file_, trackIndex_ ))
    , enabled         ( _enabled )
    , inMovie         ( _inMovie )
    , inPreview       ( _inPreview )
    , layer           ( _layer )
    , alternateGroup  ( _alternateGroup )
    , volume          ( _volume )
    , width           ( _width )
    , height          ( _height )
    , language        ( _language )
    , handlerType     ( _handlerType )
    , handlerName     ( _handlerName )
    , userDataName    ( _userDataName )
{
    fetch();
}

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

TrackModifier::~TrackModifier()
{
}

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

void
TrackModifier::dump( std::ostream& out, const string& xind )
{
    const uint32_t w = 14;
    const string eq = " = ";
    const string ind = "  ";

    out << left << xind << "track[" << trackIndex << "] id=" << trackId << '\n'
        << xind << ind << std::setw(w) << "type" << eq
        << toStringTrackType(handlerType) << '\n'
        << xind << ind << std::setw(w) << "enabled" << eq << toString(enabled)
        << '\n'
        << xind << ind << std::setw(w) << "inMovie" << eq << toString(inMovie)
        << '\n'
        << xind << ind << std::setw(w) << "inPreview" << eq
        << toString(inPreview) << '\n'
        << xind << ind << std::setw(w) << "layer" << eq << layer << '\n'
        << xind << ind << std::setw(w) << "alternateGroup" << eq
        << alternateGroup << '\n'
        << xind << ind << std::setw(w) << "volume" << eq
        << toString(volume, 8, 8) << '\n'
        << xind << ind << std::setw(w) << "width" << eq
        << toString(width, 16, 16) << '\n'
        << xind << ind << std::setw(w) << "height" << eq
        << toString(height, 16, 16) << '\n'
        << xind << ind << std::setw(w) << "language" << eq
        << bmff::enumLanguageCode.toString(language, true) << '\n'
        << xind << ind << std::setw(w) << "handlerName" << eq << handlerName;

    out << '\n'
        << xind << ind << std::setw(w) << "userDataName" << eq
        << (_props.userDataName ? userDataName : "<absent>");

    out << '\n';
}

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

void
TrackModifier::fetch()
{
    _props.update();

    const uint32_t flags = _props.flags.GetValue();
    _enabled   = flags & 0x01;
    _inMovie   = flags & 0x02;
    _inPreview = flags & 0x04;

    _layer          = _props.layer.GetValue();
    _alternateGroup = _props.alternateGroup.GetValue();
    _volume         = _props.volume.GetValue();
    _width          = _props.width.GetValue();
    _height         = _props.height.GetValue();

    _language     = _props.language.GetValue();
    _handlerType  = _props.handlerType.GetValue();
    _handlerName  = _props.handlerName.GetValue();

    if( _props.userDataName ) {
        uint8_t* buffer;
        uint32_t size;
        _props.userDataName->GetValue( &buffer, &size );
        _userDataName = string( reinterpret_cast<char*>(buffer), size );
    }
    else {
        _userDataName.clear();
    }
}

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

bool&
TrackModifier::fromString( const string& src, bool& dst )
{
    if( src == "true" )
        dst = true;
    else if ( src == "false" )
        dst = false;
    else {
        istringstream iss( src );
        iss >> dst;
        if( iss.rdstate() != ios::eofbit ) {
            ostringstream oss;
            oss << "invalid value: " << src;
            throw new Exception( oss.str(), __FILE__, __LINE__, __FUNCTION__ );
        }
    }

    return dst;
}

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

float&
TrackModifier::fromString( const string& src, float& dst )
{
    istringstream iss( src );
    iss >> dst;
    if( iss.rdstate() != ios::eofbit ) {
        ostringstream oss;
        oss << "invalid value: " << src;
        throw new Exception( oss.str(), __FILE__, __LINE__, __FUNCTION__ );
    }

    return dst;
}

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

uint16_t&
TrackModifier::fromString( const string& src, uint16_t& dst )
{
    istringstream iss( src );
    iss >> dst;
    if( iss.rdstate() != ios::eofbit ) { 
        ostringstream oss;
        oss << "invalid value: " << src;
        throw new Exception( oss.str(), __FILE__, __LINE__, __FUNCTION__ );
    }   

    return dst;
}

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

bool
TrackModifier::hasUserDataName() const
{
    return _props.userDataName != NULL;
}

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

MP4Atom&
TrackModifier::refTrackAtom( MP4File& file, uint16_t index )
{
    MP4Atom& root = *file.FindAtom( NULL );

    ostringstream oss;
    oss << "moov.trak[" << index << "]";
    MP4Atom* trak = root.FindAtom( oss.str().c_str() );
    if( !trak ) {
        oss.str( "" );
        oss << "trackIndex " << index << " not found";
        throw new Exception( oss.str(), __FILE__, __LINE__, __FUNCTION__ );
    }

    return *trak;
}

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

void
TrackModifier::removeUserDataName()
{
    MP4Atom* name = _track.FindAtom( "trak.udta.name" );
    if( name )
        name->GetParentAtom()->DeleteChildAtom( name );

    MP4Atom* udta = _track.FindAtom( "trak.udta" );
    if( udta && !udta->GetNumberOfChildAtoms() )
        udta->GetParentAtom()->DeleteChildAtom( udta );
}

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

void
TrackModifier::setAlternateGroup( uint16_t value )
{
    _props.alternateGroup.SetValue( value );
    fetch();
}

void
TrackModifier::setAlternateGroup( const string& value )
{
    uint16_t tmp;
    setAlternateGroup( fromString( value, tmp ));
}

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

void
TrackModifier::setEnabled( bool value )
{
    _enabled = value;
    _props.flags.SetValue( (_enabled ? 0x01 : 0) | (_inMovie ? 0x02 : 0) | (_inPreview ? 0x04 : 0) );
    fetch();
}

void
TrackModifier::setEnabled( const string& value )
{
    bool tmp;
    setEnabled( fromString( value, tmp ));
}

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

void
TrackModifier::setHandlerName( const string& value )
{
    _props.handlerName.SetValue( value.c_str() );
    fetch();
}
///////////////////////////////////////////////////////////////////////////////

void
TrackModifier::setHeight( float value )
{
    _props.height.SetValue( value );
    fetch();
}

void
TrackModifier::setHeight( const string& value )
{
    float tmp;
    setHeight( fromString( value, tmp ));
}

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

void
TrackModifier::setInMovie( bool value )
{
    _inMovie = value;
    _props.flags.SetValue( (_enabled ? 0x01 : 0) | (_inMovie ? 0x02 : 0) | (_inPreview ? 0x04 : 0) );
    fetch();
}

void
TrackModifier::setInMovie( const string& value )
{
    bool tmp;
    setInMovie( fromString( value, tmp ));
}

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

void
TrackModifier::setInPreview( bool value )
{
    _inPreview = value;
    _props.flags.SetValue( (_enabled ? 0x01 : 0) | (_inMovie ? 0x02 : 0) | (_inPreview ? 0x04 : 0) );
    fetch();
}

void
TrackModifier::setInPreview( const string& value )
{
    bool tmp;
    setInPreview( fromString( value, tmp ));
}

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

void
TrackModifier::setLanguage( bmff::LanguageCode value )
{
    _props.language.SetValue( value );
    fetch();
}

void
TrackModifier::setLanguage( const string& value )
{
    setLanguage( bmff::enumLanguageCode.toType( value ));
}

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

void
TrackModifier::setLayer( uint16_t value )
{
    _props.layer.SetValue( value );
    fetch();
}

void
TrackModifier::setLayer( const string& value )
{
    uint16_t tmp;
    setLayer( fromString( value, tmp ));
}

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

void
TrackModifier::setUserDataName( const string& value )
{
    if( !_props.userDataName ) {
        ostringstream oss;
        oss << "moov.trak[" << trackIndex << "]";
        file.AddDescendantAtoms( oss.str().c_str(), "udta.name" );
        _props.update();
    }

    _props.userDataName->SetValue( reinterpret_cast<const uint8_t*>(value.c_str()), (uint32_t)value.size() );
    fetch();
}

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

void
TrackModifier::setVolume( float value )
{
    _props.volume.SetValue( value );
    fetch();
}

void
TrackModifier::setVolume( const string& value )
{
    float tmp;
    setVolume( fromString( value, tmp ));
}

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

void
TrackModifier::setWidth( float value )
{
    _props.width.SetValue( value );
    fetch();
}

void
TrackModifier::setWidth( const string& value )
{
    float tmp;
    setWidth( fromString( value, tmp ));
}

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

string
TrackModifier::toString( bool value )
{
    ostringstream oss;
    oss << (value ? "true" : "false");
    return oss.str();
}

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

string
TrackModifier::toString( float value, uint8_t i, uint8_t f )
{
    ostringstream oss;
    oss << fixed << std::setprecision(f <= 8 ? 4 : 8) << value;
    return oss.str();
}

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

string
TrackModifier::toStringTrackType( const string& code )
{
    if( !code.compare( "vide" ))    // 14496-12
        return "video";
    if( !code.compare( "soun" ))    // 14496-12
        return "audio";
    if( !code.compare( "hint" ))    // 14496-12
        return "hint";

    if( !code.compare( "text" ))    // QTFF
        return "text";
    if( !code.compare( "tmcd" ))    // QTFF
        return "timecode";

    if( !code.compare( "subt" ))    // QTFF
        return "subtitle";

    return string( "(" ) + code + ")";
}

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

TrackModifier::Properties::Properties( TrackModifier& trackModifier_ )
    : _trackModifier ( trackModifier_ )
    , flags          ( static_cast<MP4Integer24Property&>   ( refProperty(  "trak.tkhd.flags" )))
    , layer          ( static_cast<MP4Integer16Property&>   ( refProperty(  "trak.tkhd.layer" )))
    , alternateGroup ( static_cast<MP4Integer16Property&>   ( refProperty(  "trak.tkhd.alternate_group" )))
    , volume         ( static_cast<MP4Float32Property&>     ( refProperty(  "trak.tkhd.volume" )))
    , width          ( static_cast<MP4Float32Property&>     ( refProperty(  "trak.tkhd.width" )))
    , height         ( static_cast<MP4Float32Property&>     ( refProperty(  "trak.tkhd.height" )))
    , language       ( static_cast<MP4LanguageCodeProperty&>( refProperty(  "trak.mdia.mdhd.language" )))
    , handlerType    ( static_cast<MP4StringProperty&>      ( refProperty(  "trak.mdia.hdlr.handlerType" )))
    , handlerName    ( static_cast<MP4StringProperty&>      ( refProperty(  "trak.mdia.hdlr.name" )))
    , userDataName   ( static_cast<MP4BytesProperty*>       ( findProperty( "trak.udta.name.value" )))
{
}

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

MP4Property*
TrackModifier::Properties::findProperty( const char* name )
{
    MP4Property* property;
    if( !_trackModifier._track.FindProperty( name, &property ))
        return NULL;

    return property;
}

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

MP4Property&
TrackModifier::Properties::refProperty( const char* name )
{
    MP4Property* property;
    if( !_trackModifier._track.FindProperty( name, &property )) {
        ostringstream oss;
        oss << "trackId " << _trackModifier.trackId << " property '" << name << "' not found";
        throw new Exception( oss.str(), __FILE__, __LINE__, __FUNCTION__ );
    }

    return *property;
}

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

void
TrackModifier::Properties::update()
{
    // update optional properties
    updateProperty( "trak.udta.name.value", reinterpret_cast<MP4Property**>( &userDataName ));
}

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

void
TrackModifier::Properties::updateProperty( const char* name, MP4Property** pp )
{
    *pp = NULL;
    _trackModifier._track.FindProperty( name, pp );
}

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

}} // namespace mp4v2::util
