//*********************************************************************************
//                               Movie.cc
//---------------------------------------------------------------------------------
// 
//---------------------------------------------------------------------------------
// Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
// Pino Toscano <pino@kde.org> (c) 2008
// Carlos Garcia Campos <carlosgc@gnome.org> (c) 2010
// Albert Astals Cid <aacid@kde.org> (c) 2010, 2017-2019
// Evgeny Stambulchik <fnevgeny@gmail.com> (c) 2019
//
// 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 <math.h>
#include "Movie.h"
#include "FileSpec.h"

MovieActivationParameters::MovieActivationParameters() {
  // default values
  floatingWindow = false;
  xPosition = 0.5;
  yPosition = 0.5;
  rate = 1.0;
  volume = 100;
  showControls = false;
  synchronousPlay = false;
  repeatMode = repeatModeOnce;
  start.units = 0;
  duration.units = 0;
  znum = 1;
  zdenum = 1;
}

MovieActivationParameters::~MovieActivationParameters() {
}

void MovieActivationParameters::parseMovieActivation(const Object* aDict) {
  Object obj1 = aDict->dictLookup("Start");
  if (obj1.isInt()) {
    // If it is representable as an integer (subject to the implementation limit for
    // integers, as described in Appendix C), it should be specified as such.

    start.units = obj1.getInt();
  } else if (obj1.isString()) {
    // If it is not representable as an integer, it should be specified as an 8-byte
    // string representing a 64-bit twos-complement integer, most significant
    // byte first.

    // UNSUPPORTED
  } else if (obj1.isArray()) {
    Array* a = obj1.getArray();

    Object tmp = a->get(0);
    if (tmp.isInt()) {
      start.units = tmp.getInt();
    }
    if (tmp.isString()) {
      // UNSUPPORTED
    }

    tmp = a->get(1);
    if (tmp.isInt()) {
      start.units_per_second = tmp.getInt();
    }
  }

  obj1 = aDict->dictLookup("Duration");
  if (obj1.isInt()) {
    duration.units = obj1.getInt();
  } else if (obj1.isString()) {
    // UNSUPPORTED
  } else if (obj1.isArray()) {
    Array* a = obj1.getArray();

    Object tmp = a->get(0);
    if (tmp.isInt()) {
      duration.units = tmp.getInt();
    }
    if (tmp.isString()) {
      // UNSUPPORTED
    }

    tmp = a->get(1);
    if (tmp.isInt()) {
      duration.units_per_second = tmp.getInt();
    }
  }

  obj1 = aDict->dictLookup("Rate");
  if (obj1.isNum()) {
    rate = obj1.getNum();
  }

  obj1 = aDict->dictLookup("Volume");
  if (obj1.isNum()) {
    // convert volume to [0 100]
    volume = int((obj1.getNum() + 1.0) * 50);
  }

  obj1 = aDict->dictLookup("ShowControls");
  if (obj1.isBool()) {
    showControls = obj1.getBool();
  }

  obj1 = aDict->dictLookup("Synchronous");
  if (obj1.isBool()) {
    synchronousPlay = obj1.getBool();
  }

  obj1 = aDict->dictLookup("Mode");
  if (obj1.isName()) {
    const char* name = obj1.getName();
    if (!strcmp(name, "Once")) {
      repeatMode = repeatModeOnce;
    } else if (!strcmp(name, "Open")) {
      repeatMode = repeatModeOpen;
    } else if (!strcmp(name, "Repeat")) {
      repeatMode = repeatModeRepeat;
    } else if (!strcmp(name,"Palindrome")) {
      repeatMode = repeatModePalindrome;
    }
  }

  obj1 = aDict->dictLookup("FWScale");
  if (obj1.isArray()) {
    // the presence of that entry implies that the movie is to be played
    // in a floating window
    floatingWindow = true;

    Array* scale = obj1.getArray();
    if (scale->getLength() >= 2) {
      Object tmp = scale->get(1);
      if (tmp.isInt()) {
        znum = tmp.getInt();
      }
      tmp = scale->get(1);
      if (tmp.isInt()) {
        zdenum = tmp.getInt();
      }
    }
  }

  obj1 = aDict->dictLookup("FWPosition");
  if (obj1.isArray()) {
    Array* pos = obj1.getArray();
    if (pos->getLength() >= 2) {
      Object tmp = pos->get(0);
      if (tmp.isNum()) {
        xPosition = tmp.getNum();
      }
      tmp = pos->get(1);
      if (tmp.isNum()) {
        yPosition = tmp.getNum();
      }
    }
  }
}

void Movie::parseMovie (const Object *movieDict) {
  fileName = nullptr;
  rotationAngle = 0;
  width = -1;
  height = -1;
  showPoster = false;

  Object obj1 = movieDict->dictLookup("F");
  Object obj2 = getFileSpecNameForPlatform(&obj1);
  if (obj2.isString()) {
    fileName = obj2.getString()->copy();
  } else {
    error (errSyntaxError, -1, "Invalid Movie");
    ok = false;
    return;
  }

  obj1 = movieDict->dictLookup("Aspect");
  if (obj1.isArray()) {
    Array* aspect = obj1.getArray();
    if (aspect->getLength() >= 2) {
      Object tmp = aspect->get(0);
      if( tmp.isNum() ) {
        width = (int)floor( tmp.getNum() + 0.5 );
      }
      tmp = aspect->get(1);
      if( tmp.isNum() ) {
        height = (int)floor( tmp.getNum() + 0.5 );
      }
    }
  }

  obj1 = movieDict->dictLookup("Rotate");
  if (obj1.isInt()) {
    // round up to 90°
    rotationAngle = (((obj1.getInt() + 360) % 360) % 90) * 90;
  }

  //
  // movie poster
  //
  poster = movieDict->dictLookupNF("Poster").copy();
  if (!poster.isNull()) {
    if (poster.isRef() || poster.isStream()) {
      showPoster = true;
    } else if (poster.isBool()) {
      showPoster = poster.getBool();
      poster.setToNull();
    } else {
      poster.setToNull();
    }
  }
}

Movie::~Movie() {
  delete fileName;
}

Movie::Movie(const Object *movieDict) {
  ok = true;

  if (movieDict->isDict())
    parseMovie(movieDict);
  else
    ok = false;
}

Movie::Movie(const Object *movieDict, const Object *aDict) {
  ok = true;

  if (movieDict->isDict()) {
    parseMovie(movieDict);
    if (aDict->isDict())
      MA.parseMovieActivation(aDict);
  } else {
    ok = false;
  }
}

Movie::Movie(const Movie &other)
{
  ok = other.ok;
  rotationAngle = other.rotationAngle;
  width = other.width;
  height = other.height;
  showPoster = other.showPoster;
  MA = other.MA;

  poster = other.poster.copy();

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

void Movie::getFloatingWindowSize(int *widthA, int *heightA)
{
  *widthA = int(width * double(MA.znum) / MA.zdenum);
  *heightA = int(height * double(MA.znum) / MA.zdenum);
}

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