///////////////////////////////////////////////////////////////////////////////
//
//  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
//      Edward Groenendaal, egroenen@@cisco.com
//
///////////////////////////////////////////////////////////////////////////////

#include "util/impl.h"

namespace mp4v2 { namespace util {

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

class SubtitleUtility : public Utility
{
private:
    enum SubtitleLongCode {
        LC_LIST = _LC_MAX,
        LC_EXPORT,
        LC_IMPORT,
        LC_REMOVE
    };

public:
    SubtitleUtility( int, char** );

protected:
    // delegates implementation
    bool utility_option( int, bool& );
    bool utility_job( JobContext& );

private:
    bool actionList   ( JobContext& );
    bool actionExport ( JobContext& );
    bool actionImport ( JobContext& );
    bool actionRemove ( JobContext& );

private:
    Group  _actionGroup;

    bool (SubtitleUtility::*_action)( JobContext& );

    string _stTextFile;
};

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

SubtitleUtility::SubtitleUtility( int argc, char** argv )
    : Utility      ( "mp4subtitle", argc, argv )
    , _actionGroup ( "ACTIONS" )
    , _action      ( NULL )
{
    // add standard options which make sense for this utility
    _group.add( STD_OPTIMIZE );
    _group.add( STD_DRYRUN );
    _group.add( STD_KEEPGOING );
    _group.add( STD_OVERWRITE );
    _group.add( STD_FORCE );
    _group.add( STD_QUIET );
    _group.add( STD_DEBUG );
    _group.add( STD_VERBOSE );
    _group.add( STD_HELP );
    _group.add( STD_VERSION );
    _group.add( STD_VERSIONX );

    _actionGroup.add( "list",   false, LC_LIST,   "list available subtitles" );
    _actionGroup.add( "export", true,  LC_EXPORT, "export subtitles to TXT", "TXT" );
    _actionGroup.add( "import", true,  LC_IMPORT, "import subtitles from TXT", "TXT" );
    _actionGroup.add( "remove", false, LC_REMOVE, "remove all subtitles" );
    _groups.push_back( &_actionGroup );

    _usage = "[OPTION]... ACTION file...";
    _description =
        // 79-cols, inclusive, max desired width
        // |----------------------------------------------------------------------------|
        "\nFor each mp4 file specified, perform the specified ACTION. An action must be"
        "\nspecified. Some options are not applicable to some actions.";
}

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

bool
SubtitleUtility::actionExport( JobContext& job )
{
    job.fileHandle = MP4Read( job.file.c_str() );
    if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
        return herrf( "unable to open for read: %s\n", job.file.c_str() );

    verbose1f( "NOT IMPLEMENTED\n" );
    return FAILURE;
}

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

bool
SubtitleUtility::actionImport( JobContext& job )
{
    job.fileHandle = MP4Modify( job.file.c_str() );
    if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
        return herrf( "unable to open for write: %s\n", job.file.c_str() );

    verbose1f( "NOT IMPLEMENTED\n" );
    return FAILURE;
}

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

bool
SubtitleUtility::actionList( JobContext& job )
{
    job.fileHandle = MP4Read( job.file.c_str() );
    if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
        return herrf( "unable to open for read: %s\n", job.file.c_str() );

    verbose1f( "NOT IMPLEMENTED\n" );
    return FAILURE;
}

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

bool
SubtitleUtility::actionRemove( JobContext& job )
{
    job.fileHandle = MP4Modify( job.file.c_str() );
    if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
        return herrf( "unable to open for write: %s\n", job.file.c_str() );

    verbose1f( "NOT IMPLEMENTED" );
    return FAILURE;
}

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

bool
SubtitleUtility::utility_job( JobContext& job )
{
    if( !_action )
        return herrf( "no action specified\n" );

    return (this->*_action)( job );
}

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

bool
SubtitleUtility::utility_option( int code, bool& handled )
{
    handled = true;

    switch( code ) {
        case LC_LIST:
            _action = &SubtitleUtility::actionList;
            break;

        case LC_EXPORT:
            _action = &SubtitleUtility::actionExport;
            _stTextFile = prog::optarg;
            if( _stTextFile.empty() )
                return herrf( "invalid TXT file: empty-string\n" );
            break;

        case LC_IMPORT:
            _action = &SubtitleUtility::actionImport;
            _stTextFile = prog::optarg;
            if( _stTextFile.empty() )
                return herrf( "invalid TXT file: empty-string\n" );
            break;

        case LC_REMOVE:
            _action = &SubtitleUtility::actionRemove;
            break;

        default:
            handled = false;
            break;
    }

    return SUCCESS;
}

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

}} // namespace mp4v2::util

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

extern "C"
int main( int argc, char** argv )
{
    mp4v2::util::SubtitleUtility util( argc, argv );
    return util.process();
}
