'use strict';

exports.__esModule = true;
exports.default = undefined;

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _es6Symbol = require('es6-symbol');

var _es6Symbol2 = _interopRequireDefault(_es6Symbol);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var _impl = (0, _es6Symbol2.default)('impl');

/**
	The base class for all shadow state properties. The api is purposefully spartan so as to not polute
	the namespace of shadow state objects. This class does provide implementations for the standard
	javascript methods `toJSON()` and `toString()`. `toJson()` is very useful in the javascript console
	to obtain the actual state being proxied by this shadow state property.

	Each non-primitive shadow state property exposes four special, f.lux specific methods that are
	named so as to be unlikely to collide with normal method names:

	<ul>
		<li>
			`_()` - gets this `Shadow` object. This method may seem superflous but when using
				the `@shadow` decorator this allows property methods to be written to work when invoked
				through the shadow state property or directly using `this` within `Property` methods.
		</li>
		<li>
			`__()` - gets the backing {@link ShadowImpl} instance for this shadow property
		</li>
		<li>
			`$()` - gets the {@link Access} object for obtaining information about a property.
		</li>
		<li>
			`$$()` - gets the {@link Property} managing this shadow state property.
		</li>
	</ul>

	@see {@link ArrayShadow}
	@see {@link IndexedShadow}
	@see {@link MapShadow}
*/

var Shadow = function () {
	function Shadow(impl) {
		_classCallCheck(this, Shadow);

		this[_impl] = impl;

		// easy debug access to the raw state
		if (process.env.NODE_ENV !== 'production') {
			Object.defineProperty(this, '__state__', { enumerable: false, value: impl.state() });
		}
	}

	/**
 	 Gets this `Shadow` object. This method may seem superflous but when using the `@shadow`
 	 decorator this allows property methods to be written to work when invoked through the shadow
 	 state property or directly using `this` within `Property` methods.
 		@return {Shadow}
 */


	_createClass(Shadow, [{
		key: '_',
		value: function _() {
			return this;
		}

		/**
  	Get the backing {@link ShadowImpl} instance for this shadow property.
  		@return {ShadowImpl}
  */

	}, {
		key: '__',
		value: function __() {
			return this[_impl];
		}

		/**
  	Gets the {@link Access} object for obtaining information about a property.
  		@return {Access}
  */

	}, {
		key: '$',
		value: function $() {
			return this[_impl].access();
		}

		/**
  	Gets the {@link Property} managing this shadow state property.
  		@return {Property}
  */

	}, {
		key: '$$',
		value: function $$() {
			return this[_impl].property();
		}

		/**
  	Gets the actual state property being proxied by this shadow state property.
  		Note: this is the actual state so critical it is not mutated in any way.
  		@return {Object|Array}
  */

	}, {
		key: 'toJSON',
		value: function toJSON() {
			return this[_impl].state();
		}
	}, {
		key: 'toString',
		value: function toString() {
			return JSON.stringify(this);
		}
	}]);

	return Shadow;
}();

exports.default = Shadow;