//*********************************************************************************
//                               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
//
// 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.isNull()) {
    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.isNull()) {
    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);
}
