(function () {
    var defs = {}; // id -> {dependencies, definition, instance (possibly undefined)}

// Used when there is no 'main' module.
// The name is probably (hopefully) unique so minification removes for releases.
    var register_3795 = function (id) {
        var module = dem(id);
        var fragments = id.split('.');
        var target = Function('return this;')();
        for (var i = 0; i < fragments.length - 1; ++i) {
            if (target[fragments[i]] === undefined) { target[fragments[i]] = {}; }
            target = target[fragments[i]];
        }
        target[fragments[fragments.length - 1]] = module;
    };

    var instantiate = function (id) {
        var actual = defs[id];
        var dependencies = actual.deps;
        var definition = actual.defn;
        var len = dependencies.length;
        var instances = new Array(len);
        for (var i = 0; i < len; ++i) { instances[i] = dem(dependencies[i]); }
        var defResult = definition.apply(null, instances);
        if (defResult === undefined) { throw 'module [' + id + '] returned undefined'; }
        actual.instance = defResult;
    };

    var def = function (id, dependencies, definition) {
        if (typeof id !== 'string') { throw 'module id must be a string'; } else if (dependencies === undefined) { throw 'no dependencies for ' + id; } else if (definition === undefined) { throw 'no definition function for ' + id; }
        defs[id] = {
            deps: dependencies,
            defn: definition,
            instance: undefined
        };
    };

    var dem = function (id) {
        var actual = defs[id];
        if (actual === undefined) { throw 'module [' + id + '] was undefined'; } else if (actual.instance === undefined) { instantiate(id); }
        return actual.instance;
    };

    var req = function (ids, callback) {
        var len = ids.length;
        var instances = new Array(len);
        for (var i = 0; i < len; ++i) { instances[i] = dem(ids[i]); }
        callback.apply(null, instances);
    };

    var ephox = {};

    ephox.bolt = {
        module: {
            api: {
                define: def,
                require: req,
                demand: dem
            }
        }
    };

    var define = def;
    var require = req;
    var demand = dem;
// this helps with minification when using a lot of global references
    var defineGlobal = function (id, ref) {
        define(id, [], function () { return ref; });
    };
/* jsc
["tinymce.plugins.fullscreen.Plugin","ephox.katamari.api.Cell","tinymce.core.PluginManager","tinymce.plugins.fullscreen.api.Api","tinymce.plugins.fullscreen.api.Commands","tinymce.plugins.fullscreen.ui.Buttons","global!tinymce.util.Tools.resolve","tinymce.plugins.fullscreen.core.Actions","global!document","global!window","tinymce.core.dom.DOMUtils","tinymce.plugins.fullscreen.api.Events"]
jsc */
    define(
  'ephox.katamari.api.Cell',

        [
        ],

  function () {
      var Cell = function (initial) {
          var value = initial;

          var get = function () {
              return value;
          };

          var set = function (v) {
              value = v;
          };

          var clone = function () {
              return Cell(get());
          };

          return {
              get: get,
              set: set,
              clone: clone
          };
      };

      return Cell;
  }
);

    defineGlobal('global!tinymce.util.Tools.resolve', tinymce.util.Tools.resolve);
/**
 * ResolveGlobal.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

    define(
  'tinymce.core.PluginManager',
        [
            'global!tinymce.util.Tools.resolve'
        ],
  function (resolve) {
      return resolve('tinymce.PluginManager');
  }
);

/**
 * Api.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

    define(
  'tinymce.plugins.fullscreen.api.Api',
        [
        ],
  function () {
      var get = function (fullscreenState) {
          return {
              isFullscreen: function () {
                  return fullscreenState.get() !== null;
              }
          };
      };

      return {
          get: get
      };
  }
);

    defineGlobal('global!document', document);
    defineGlobal('global!window', window);
/**
 * ResolveGlobal.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

    define(
  'tinymce.core.dom.DOMUtils',
        [
            'global!tinymce.util.Tools.resolve'
        ],
  function (resolve) {
      return resolve('tinymce.dom.DOMUtils');
  }
);

/**
 * Events.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

    define(
  'tinymce.plugins.fullscreen.api.Events',
        [
        ],
  function () {
      var fireFullscreenStateChanged = function (editor, state) {
          editor.fire('FullscreenStateChanged', { state: state });
      };

      return {
          fireFullscreenStateChanged: fireFullscreenStateChanged
      };
  }
);

/**
 * Actions.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

    define(
  'tinymce.plugins.fullscreen.core.Actions',
        [
            'global!document',
            'global!window',
            'tinymce.core.dom.DOMUtils',
            'tinymce.plugins.fullscreen.api.Events'
        ],
  function (document, window, DOMUtils, Events) {
      var DOM = DOMUtils.DOM;

      var getWindowSize = function () {
          var w, h, win = window, doc = document;
          var body = doc.body;

      // Old IE
          if (body.offsetWidth) {
              w = body.offsetWidth;
              h = body.offsetHeight;
          }

      // Modern browsers
          if (win.innerWidth && win.innerHeight) {
              w = win.innerWidth;
              h = win.innerHeight;
          }

          return { w: w, h: h };
      };

      var getScrollPos = function () {
          var vp = DOM.getViewPort();

          return {
              x: vp.x,
              y: vp.y
          };
      };

      var setScrollPos = function (pos) {
          window.scrollTo(pos.x, pos.y);
      };

      var toggleFullscreen = function (editor, fullscreenInfo) {
          var body = document.body, documentElement = document.documentElement, editorContainerStyle;
          var editorContainer, iframe, iframeStyle;

          var resize = function () {
              DOM.setStyle(iframe, 'height', getWindowSize().h - (editorContainer.clientHeight - iframe.clientHeight));
          };

          var removeResize = function () {
              DOM.unbind(window, 'resize', resize);
          };

          editorContainer = editor.getContainer();
          editorContainerStyle = editorContainer.style;
          iframe = editor.getContentAreaContainer().firstChild;
          iframeStyle = iframe.style;

          if (!fullscreenInfo) {
              var newFullScreenInfo = {
                  scrollPos: getScrollPos(),
                  containerWidth: editorContainerStyle.width,
                  containerHeight: editorContainerStyle.height,
                  iframeWidth: iframeStyle.width,
                  iframeHeight: iframeStyle.height,
                  resizeHandler: resize,
                  removeHandler: removeResize
              };

              iframeStyle.width = iframeStyle.height = '100%';
              editorContainerStyle.width = editorContainerStyle.height = '';

              DOM.addClass(body, 'mce-fullscreen');
              DOM.addClass(documentElement, 'mce-fullscreen');
              DOM.addClass(editorContainer, 'mce-fullscreen');

              DOM.bind(window, 'resize', resize);
              editor.on('remove', removeResize);

              resize();

              Events.fireFullscreenStateChanged(editor, true);

              return newFullScreenInfo;
          } else {
              iframeStyle.width = fullscreenInfo.iframeWidth;
              iframeStyle.height = fullscreenInfo.iframeHeight;

              if (fullscreenInfo.containerWidth) {
                  editorContainerStyle.width = fullscreenInfo.containerWidth;
              }

              if (fullscreenInfo.containerHeight) {
                  editorContainerStyle.height = fullscreenInfo.containerHeight;
              }

              DOM.removeClass(body, 'mce-fullscreen');
              DOM.removeClass(documentElement, 'mce-fullscreen');
              DOM.removeClass(editorContainer, 'mce-fullscreen');
              setScrollPos(fullscreenInfo.scrollPos);

              DOM.unbind(window, 'resize', fullscreenInfo.resizeHandler);
              editor.off('remove', fullscreenInfo.removeHandler);

              Events.fireFullscreenStateChanged(editor, false);

              return null;
          }
      };

      return {
          toggleFullscreen: toggleFullscreen
      };
  }
);

/**
 * Commands.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

    define(
  'tinymce.plugins.fullscreen.api.Commands',
        [
            'tinymce.plugins.fullscreen.core.Actions'
        ],
  function (Actions) {
      var register = function (editor, fullscreenState) {
          editor.addCommand('mceFullScreen', function () {
              fullscreenState.set(Actions.toggleFullscreen(editor, fullscreenState.get()));
          });
      };

      return {
          register: register
      };
  }
);

/**
 * Buttons.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

    define(
  'tinymce.plugins.fullscreen.ui.Buttons',
        [
        ],
  function () {
      var postRender = function (editor) {
          return function (e) {
              var ctrl = e.control;

              editor.on('FullscreenStateChanged', function (e) {
                  ctrl.active(e.state);
              });
          };
      };

      var register = function (editor) {
          editor.addMenuItem('fullscreen', {
              text: 'Fullscreen',
              shortcut: 'Ctrl+Shift+F',
              selectable: true,
              cmd: 'mceFullScreen',
              onPostRender: postRender(editor),
              context: 'view'
          });

          editor.addButton('fullscreen', {
              tooltip: 'Fullscreen',
              shortcut: 'Ctrl+Shift+F',
              cmd: 'mceFullScreen',
              onPostRender: postRender(editor)
          });
      };

      return {
          register: register
      };
  }
);
/**
 * Plugin.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

    define(
  'tinymce.plugins.fullscreen.Plugin',
        [
            'ephox.katamari.api.Cell',
            'tinymce.core.PluginManager',
            'tinymce.plugins.fullscreen.api.Api',
            'tinymce.plugins.fullscreen.api.Commands',
            'tinymce.plugins.fullscreen.ui.Buttons'
        ],
  function (Cell, PluginManager, Api, Commands, Buttons) {
      PluginManager.add('fullscreen', function (editor) {
          var fullscreenState = Cell(null);

          Commands.register(editor, fullscreenState);
          Buttons.register(editor);

          editor.addShortcut('Ctrl+Shift+F', '', 'mceFullScreen');

          return Api.get(fullscreenState);
      });

      return function () { };
  }
);
    dem('tinymce.plugins.fullscreen.Plugin')();
})();
