//*********************************************************************************
//                               Rendition.cc
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
// Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
// Pino Toscano <pino@kde.org> (c) 2008
// Carlos Garcia Campos <carlosgc@gnome.org> (c) 2010
// Tobias Koenig <tobias.koenig@kdab.com> (c) 2012
// Albert Astals Cid <aacid@kde.org> (C) 2017, 2018
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//*********************************************************************************

#include <cmath>
#include "Rendition.h"
#include "FileSpec.h"

MediaWindowParameters::MediaWindowParameters()
{
    // default values
    type = windowEmbedded;
    width = -1;
    height = -1;
    relativeTo = windowRelativeToDocument;
    XPosition = 0.5;
    YPosition = 0.5;
    hasTitleBar = true;
    hasCloseButton = true;
    isResizeable = true;
}

MediaWindowParameters::~MediaWindowParameters() { }

void MediaWindowParameters::parseFWParams(Object *obj)
{
    Object tmp = obj->dictLookup("D");
    if (tmp.isArray()) {
        Array *dim = tmp.getArray();

        if (dim->getLength() >= 2) {
            Object dd = dim->get(0);
            if (dd.isInt()) {
                width = dd.getInt();
            }

            dd = dim->get(1);
            if (dd.isInt()) {
                height = dd.getInt();
            }
        }
    }

    tmp = obj->dictLookup("RT");
    if (tmp.isInt()) {
        int t = tmp.getInt();
        switch (t) {
        case 0:
            relativeTo = windowRelativeToDocument;
            break;
        case 1:
            relativeTo = windowRelativeToApplication;
            break;
        case 2:
            relativeTo = windowRelativeToDesktop;
            break;
        }
    }

    tmp = obj->dictLookup("P");
    if (tmp.isInt()) {
        int t = tmp.getInt();

        switch (t) {
        case 0: // Upper left
            XPosition = 0.0;
            YPosition = 0.0;
            break;
        case 1: // Upper Center
            XPosition = 0.5;
            YPosition = 0.0;
            break;
        case 2: // Upper Right
            XPosition = 1.0;
            YPosition = 0.0;
            break;
        case 3: // Center Left
            XPosition = 0.0;
            YPosition = 0.5;
            break;
        case 4: // Center
            XPosition = 0.5;
            YPosition = 0.5;
            break;
        case 5: // Center Right
            XPosition = 1.0;
            YPosition = 0.5;
            break;
        case 6: // Lower Left
            XPosition = 0.0;
            YPosition = 1.0;
            break;
        case 7: // Lower Center
            XPosition = 0.5;
            YPosition = 1.0;
            break;
        case 8: // Lower Right
            XPosition = 1.0;
            YPosition = 1.0;
            break;
        }
    }

    tmp = obj->dictLookup("T");
    if (tmp.isBool()) {
        hasTitleBar = tmp.getBool();
    }
    tmp = obj->dictLookup("UC");
    if (tmp.isBool()) {
        hasCloseButton = tmp.getBool();
    }
    tmp = obj->dictLookup("R");
    if (tmp.isInt()) {
        isResizeable = (tmp.getInt() != 0);
    }
}

MediaParameters::MediaParameters()
{
    // instanciate to default values

    volume = 100;
    fittingPolicy = fittingUndefined;
    autoPlay = true;
    repeatCount = 1.0;
    opacity = 1.0;
    showControls = false;
    duration = 0;
}

MediaParameters::~MediaParameters() { }

void MediaParameters::parseMediaPlayParameters(Object *obj)
{
    Object tmp = obj->dictLookup("V");
    if (tmp.isInt()) {
        volume = tmp.getInt();
    }

    tmp = obj->dictLookup("C");
    if (tmp.isBool()) {
        showControls = tmp.getBool();
    }

    tmp = obj->dictLookup("F");
    if (tmp.isInt()) {
        int t = tmp.getInt();

        switch (t) {
        case 0:
            fittingPolicy = fittingMeet;
            break;
        case 1:
            fittingPolicy = fittingSlice;
            break;
        case 2:
            fittingPolicy = fittingFill;
            break;
        case 3:
            fittingPolicy = fittingScroll;
            break;
        case 4:
            fittingPolicy = fittingHidden;
            break;
        case 5:
            fittingPolicy = fittingUndefined;
            break;
        }
    }

    // duration parsing
    // duration's default value is set to 0, which means : intrinsinc media duration
    tmp = obj->dictLookup("D");
    if (tmp.isDict()) {
        Object oname = tmp.dictLookup("S");
        if (oname.isName()) {
            const char *name = oname.getName();
            if (!strcmp(name, "F")) {
                duration = -1; // infinity
            } else if (!strcmp(name, "T")) {
                Object ddict = tmp.dictLookup("T");
                if (ddict.isDict()) {
                    Object tmp2 = ddict.dictLookup("V");
                    if (tmp2.isNum()) {
                        duration = (unsigned long)(tmp2.getNum());
                    }
                }
            }
        }
    }

    tmp = obj->dictLookup("A");
    if (tmp.isBool()) {
        autoPlay = tmp.getBool();
    }

    tmp = obj->dictLookup("RC");
    if (tmp.isNum()) {
        repeatCount = tmp.getNum();
    }
}

void MediaParameters::parseMediaScreenParameters(Object *obj)
{
    Object tmp = obj->dictLookup("W");
    if (tmp.isInt()) {
        int t = tmp.getInt();

        switch (t) {
        case 0:
            windowParams.type = MediaWindowParameters::windowFloating;
            break;
        case 1:
            windowParams.type = MediaWindowParameters::windowFullscreen;
            break;
        case 2:
            windowParams.type = MediaWindowParameters::windowHidden;
            break;
        case 3:
            windowParams.type = MediaWindowParameters::windowEmbedded;
            break;
        }
    }

    // background color
    tmp = obj->dictLookup("B");
    if (tmp.isArray()) {
        Array *color = tmp.getArray();

        Object component = color->get(0);
        bgColor.r = component.getNum();

        component = color->get(1);
        bgColor.g = component.getNum();

        component = color->get(2);
        bgColor.b = component.getNum();
    }

    // opacity
    tmp = obj->dictLookup("O");
    if (tmp.isNum()) {
        opacity = tmp.getNum();
    }

    if (windowParams.type == MediaWindowParameters::windowFloating) {
        Object winDict = obj->dictLookup("F");
        if (winDict.isDict()) {
            windowParams.parseFWParams(&winDict);
        }
    }
}

MediaRendition::~MediaRendition()
{
    delete fileName;
    delete contentType;
}

MediaRendition::MediaRendition(Object *obj)
{
    bool hasClip = false;

    ok = true;
    fileName = nullptr;
    contentType = nullptr;
    isEmbedded = false;

    //
    // Parse media clip data
    //
    Object tmp2 = obj->dictLookup("C");
    if (tmp2.isDict()) { // media clip
        hasClip = true;
        Object tmp = tmp2.dictLookup("S");
        if (tmp.isName()) {
            if (!strcmp(tmp.getName(), "MCD")) { // media clip data
                Object obj1 = tmp2.dictLookup("D");
                if (obj1.isDict()) {
                    Object obj2 = obj1.dictLookup("F");
                    if (obj2.isString()) {
                        fileName = obj2.getString()->copy();
                    }
                    obj2 = obj1.dictLookup("EF");
                    if (obj2.isDict()) {
                        Object embedded = obj2.dictLookup("F");
                        if (embedded.isStream()) {
                            isEmbedded = true;
                            embeddedStreamObject = embedded.copy();
                        }
                    }

                    // TODO: D might be a form XObject too
                } else {
                    error(errSyntaxError, -1, "Invalid Media Clip Data");
                    ok = false;
                }

                // FIXME: ignore CT if D is a form XObject
                obj1 = tmp2.dictLookup("CT");
                if (obj1.isString()) {
                    contentType = obj1.getString()->copy();
                }
            } else if (!strcmp(tmp.getName(), "MCS")) { // media clip data
                // TODO
            }
        } else {
            error(errSyntaxError, -1, "Invalid Media Clip");
            ok = false;
        }
    }

    if (!ok) {
        return;
    }

    //
    // parse Media Play Parameters
    tmp2 = obj->dictLookup("P");
    if (tmp2.isDict()) { // media play parameters
        Object params = tmp2.dictLookup("MH");
        if (params.isDict()) {
            MH.parseMediaPlayParameters(&params);
        }
        params = tmp2.dictLookup("BE");
        if (params.isDict()) {
            BE.parseMediaPlayParameters(&params);
        }
    } else if (!hasClip) {
        error(errSyntaxError, -1, "Invalid Media Rendition");
        ok = false;
    }

    //
    // parse Media Screen Parameters
    tmp2 = obj->dictLookup("SP");
    if (tmp2.isDict()) { // media screen parameters
        Object params = tmp2.dictLookup("MH");
        if (params.isDict()) {
            MH.parseMediaScreenParameters(&params);
        }
        params = tmp2.dictLookup("BE");
        if (params.isDict()) {
            BE.parseMediaScreenParameters(&params);
        }
    }
}

MediaRendition::MediaRendition(const MediaRendition &other)
{
    ok = other.ok;
    MH = other.MH;
    BE = other.BE;
    isEmbedded = other.isEmbedded;
    embeddedStreamObject = other.embeddedStreamObject.copy();

    if (other.contentType) {
        contentType = other.contentType->copy();
    } else {
        contentType = nullptr;
    }

    if (other.fileName) {
        fileName = other.fileName->copy();
    } else {
        fileName = nullptr;
    }
}

void MediaRendition::outputToFile(FILE *fp)
{
    if (!isEmbedded) {
        return;
    }

    embeddedStreamObject.streamReset();

    while (true) {
        int c = embeddedStreamObject.streamGetChar();
        if (c == EOF) {
            break;
        }

        fwrite(&c, 1, 1, fp);
    }
}

MediaRendition *MediaRendition::copy() const
{
    return new MediaRendition(*this);
}

// TODO: SelectorRendition
