// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var assert = require('assert');
var canvas = require('./widgets/canvas-widget');
var document = require('global/document');
var domready = require('domready');
var format = require('format');
var h = require('mercury').h;
var hg = require('mercury');
var window = require('global/window');

// Allow debugging in a normal browser.
window.android = window.android || {
  setPageCount: noop
};

domready(function ondomready() {
  debug('domready');

  var atom = state({});

  // Watch for the total page number changes and give the new value to the
  // Android client.
  atom.pages.total(function totalchange(current) {
    window.android.setPageCount(current);
  });

  window.atom = atom;
  window.client = {
    open: function openPDF(href) {
      open(atom, { href: href });
    },
    page: function pagePDF(number) {
      page(atom, { number: number });
    },
    zoom: function zoomPDF(value) {
      zoom(atom, { value: value });
    }
  };

  hg.app(document.body, atom, render);

  return;
});

function state(options) {
  var atom = hg.state({
    debug: hg.value(options.debug || true),
    progress: hg.value(0),
    pdf: hg.struct({
      document: hg.value(null),
      page: hg.value(null),
    }),
    pages: hg.struct({
      current: hg.value(1),
      total: hg.value(0),
    }),
    scale: hg.value(1),
    ratio: hg.value(window.devicePixelRatio || 1),
    width: hg.value(window.innerWidth),
    height: hg.value(window.innerHeight),
    channels: {
      open: open,
      page: page,
      zoom: zoom
    }
  });

  return atom;
}

function open(state, data) {
  assert.ok(data.href, 'data.href required');
  debug('opening PDF file: %s', data.href);

  var promise = PDFJS.getDocument(data.href, null, password, progress);
  promise.then(success, error);

  function password() {
    var message = format('Password required to open: "%s"', data.href);
    var err = new Error(message);
    error(err);
  }

  function progress(update) {
    // Some servers or situations might not return the content-length header
    // which is proxied to update.total. Skip updating the progress if this
    // value is not set.
    if (!update.total) {
      return;
    }

    var float = (update.loaded/update.total) * 100;
    var value = Math.floor(float);

    // For some reason the update.loaded value above can be higher than the
    // update.total value, in that case we can assume the progress is 100%.
    if (value > 100) {
      value = 100;
    }

    state.progress.set(value);
  }

  function success(pdf) {
    state.pdf.document.set(pdf);
    state.pages.total.set(pdf.numPages);
    page(state, { number: 1 });
  }
}

function page(state, data) {
  assert.ok(data.number, 'data.number required');

  var pdf = state.pdf.document();
  var total = state.pages.total();
  var number = data.number;

  // Skip invalid operations.
  if (number === 0 || !pdf || number > total) {
    return;
  }

  debug('loading page "%s"', number);

  pdf.getPage(number).then(success, error);

  function success(page) {
    debug('loaded page "%s"', number);
    var width = page.getViewport(1).width;
    var scale = state.width() / width;
    var viewport = page.getViewport(scale);

    // Reset the scroll position on page change.
    window.scroll(0, 0) ;

    // Update the state.
    state.pdf.page.set(page);
    state.scale.set(scale);
    state.height.set(viewport.height);
    state.pages.current.set(number);
  }
}

function zoom(state, data) {
  assert.ok(data.value, 'data.value is required');

  // Ignore if the page object is unavailable.
  if (!state.pdf.page()) {
    return;
  }

  debug('zooming from "%s" to "%s"', state.scale(), data.value);

  var page = state.pdf.page();
  var viewport = page.getViewport(data.value);

  // NOTE: By default this will zoom from the center of the viewport, some extra
  // work will be required zoom from the center location of a pinch gesture.
  state.width.set(viewport.width);
  state.height.set(viewport.height);
  state.scale.set(data.value);
}

function render(state) {
  return h('.pdf-viewer', [
    canvas(draw, state)
  ]);
}


function draw(context, state, done) {
  // Skip render if missing the PDFJS page object.
  if (!state.pdf.page) {
    done();
    return;
  }

  state.pdf.page.render({
    canvasContext: context,
    viewport: state.pdf.page.getViewport(state.scale)
  }).promise.then(done, error);
}

// TODO(jasoncampbell): Add better error reporting and exception capturing.
function error(err) {
  throw err;
}

function noop() {}

function debug(template, value) {
  // Noop if debugging is disabled.
  if (typeof window.atom === 'undefined' || !window.atom.debug()) {
    return;
  }

  // The logging in Android Studio only shows the template string when calling
  // console.log directly, pre-fromatting allows the logs to show the correct
  // information.
  template = 'pdf-viewer: ' + template;
  var message = format.apply(null, arguments);
  console.log(message);
}
