// Generated by CoffeeScript 1.9.0
(function() {
  var CSON, fsUtil, pathUtil, requireFreshSafe;

  fsUtil = require('safefs');

  pathUtil = require('path');

  requireFreshSafe = require('requirefresh').requireFreshSafe;

  CSON = (function() {
    function CSON() {}

    CSON.prototype.getOptions = function(opts) {
      if (opts == null) {
        opts = {};
      }
      if (opts.format == null) {
        opts.format = null;
      }
      if (opts.filename == null) {
        opts.filename = null;
      }
      if (opts.filename) {
        opts.filename = pathUtil.resolve(opts.filename);
        if (opts.format == null) {
          opts.format = this.getFormat(opts.filename);
        }
      }
      if (opts.json == null) {
        opts.json = true;
      }
      if (opts.cson == null) {
        opts.cson = true;
      }
      if (opts.javascript == null) {
        opts.javascript = false;
      }
      if (opts.coffeescript == null) {
        opts.coffeescript = false;
      }
      return opts;
    };

    CSON.prototype.getFormat = function(file) {
      switch (pathUtil.extname(file)) {
        case '.json':
          return 'json';
        case '.cson':
          return 'cson';
        case '.coffee':
          return 'coffeescript';
        case '.js':
          return 'javascript';
        default:
          return null;
      }
    };

    CSON.prototype.stringify = function(data, opts) {
      return this.createString(data, opts);
    };

    CSON.prototype.parse = function(data, opts) {
      return this.parseString(data, opts);
    };

    CSON.prototype.load = function(data, opts) {
      return this.parseFile(data, opts);
    };

    CSON.prototype.require = function(data, opts) {
      return this.requireFile(data, opts);
    };

    CSON.prototype.createString = function(data, opts) {
      return this.action('createString', 'create', 'String', data, opts);
    };

    CSON.prototype.parseString = function(data, opts) {
      return this.action('parseString', 'parse', 'String', data, opts);
    };

    CSON.prototype.parseFile = function(data, opts) {
      return this.action('parseFile', 'parse', 'File', data, opts);
    };

    CSON.prototype.requireFile = function(data, opts) {
      return this.action('requireFile', 'require', 'File', data, opts);
    };

    CSON.prototype.action = function(action, prefix, suffix, data, opts) {
      var _ref;
      if (suffix == null) {
        suffix = '';
      }
      if (opts == null) {
        opts = {};
      }
      switch (action) {
        case 'requireFile':
        case 'parseFile':
          if (opts.filename == null) {
            opts.filename = data;
          }
      }
      opts = this.getOptions(opts);
      if ((_ref = opts.format) === null || _ref === 'cson') {
        if (opts.cson === true) {
          return this[prefix + 'CSON' + suffix](data, opts);
        } else {
          return new Error("CSON." + action + ": Desired format is CSON however CSON is disabled by an option");
        }
      } else if (opts.format === 'json') {
        if (opts.json === true) {
          return this[prefix + 'JSON' + suffix](data, opts);
        } else {
          return new Error("CSON." + action + ": Desired format is JSON however JSON is disabled by an option");
        }
      } else if (opts.format === 'javascript') {
        if (opts.javascript === true) {
          return this[prefix + 'JS' + suffix](data, opts);
        } else {
          return new Error("CSON." + action + ": Desired format is JavaScript however JavaScript is disabled by an option");
        }
      } else if (opts.format === 'coffeescript') {
        if (opts.coffeescript === true) {
          return this[prefix + 'CS' + suffix](data, opts);
        } else {
          return new Error("CSON." + action + ": Desired format is CoffeeScript however CoffeeScript is disabled by an option");
        }
      } else {
        return new Error("CSON." + action + ": Desired format is not supported");
      }
    };

    CSON.prototype.createJSONString = function(data, opts) {
      var err;
      opts = this.getOptions(opts);
      if (opts.visitor == null) {
        opts.visitor = null;
      }
      if (opts.indent == null) {
        opts.indent = '  ';
      }
      try {
        return JSON.stringify(data, opts.visitor, opts.indent);
      } catch (_error) {
        err = _error;
        return new Error(err);
      }
    };

    CSON.prototype.createCSONString = function(data, opts) {
      var err;
      opts = this.getOptions(opts);
      if (opts.visitor == null) {
        opts.visitor = null;
      }
      if (opts.indent == null) {
        opts.indent = '\t';
      }
      try {
        return require('cson-parser').stringify(data, opts.visitor, opts.indent);
      } catch (_error) {
        err = _error;
        return new Error(err);
      }
    };

    CSON.prototype.createCSString = function(data, opts) {
      return new Error('CSON.createCS: Creating CoffeeScript code is not yet supported');

      /*
      		Potentially we could use something like the following from CSON v1
      		However the JSON.stringify gets rid of functions...
      		which is the entire point of the coffee-script mode over the CSON mode...
      		So until we figure out how to toString() an object and keep the functions intact,
      		unsafe stringifying to CSON or CS or JS won't happen.
      
      		Perhaps https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toSource
      		will be of use one day
      
      		src = "var result = #{JSON.stringify obj}"
      		result = require('js2coffee').build(src, opts).code
      		result = result.replace(/^\s*result\s*\=\s/, '')
      		if /^\s/.test(result) is false
      			result = result.trim()
      		if typeof obj is 'object'
      			unless Array.isArray(obj)
      				result = '{'+result+'}'  unless result is '{}'
      		return result
       */
    };

    CSON.prototype.createJSString = function(data, opts) {
      return new Error('CSON.createJS: Creating JavaScript code is not yet supported');
    };

    CSON.prototype.parseJSONString = function(data, opts) {
      var err;
      try {
        return JSON.parse(data);
      } catch (_error) {
        err = _error;
        return new Error(err);
      }
    };

    CSON.prototype.parseCSONString = function(data, opts) {
      var err;
      try {
        return require('cson-parser').parse(data);
      } catch (_error) {
        err = _error;
        return new Error(err);
      }
    };

    CSON.prototype.parseJSString = function(data, opts) {
      var err;
      opts = this.getOptions(opts);
      if (opts.context == null) {
        opts.context = {};
      }
      try {
        return require('vm').runInNewContext(data, opts.context, opts.filename);
      } catch (_error) {
        err = _error;
        return new Error(err);
      }
    };

    CSON.prototype.parseCSString = function(data, opts) {
      var err;
      opts = this.getOptions(opts);
      if (opts.sandbox == null) {
        opts.sandbox = {};
      }
      try {
        return require('coffee-script')["eval"](data, opts);
      } catch (_error) {
        err = _error;
        return new Error(err);
      }
    };

    CSON.prototype.parseJSONFile = function(file, opts) {
      var result;
      result = fsUtil.readFileSync(file);
      if (result instanceof Error) {
        return result;
      } else {
        return this.parseJSONString(result.toString(), opts);
      }
    };

    CSON.prototype.parseCSONFile = function(file, opts) {
      var result;
      result = fsUtil.readFileSync(file);
      if (result instanceof Error) {
        return result;
      } else {
        return this.parseCSONString(result.toString(), opts);
      }
    };

    CSON.prototype.parseJSFile = function(file, opts) {
      var result;
      result = fsUtil.readFileSync(file);
      if (result instanceof Error) {
        return result;
      } else {
        return this.parseJSString(result.toString(), opts);
      }
    };

    CSON.prototype.parseCSFile = function(file, opts) {
      var result;
      result = fsUtil.readFileSync(file);
      if (result instanceof Error) {
        return result;
      } else {
        return this.parseCSString(result.toString(), opts);
      }
    };

    CSON.prototype.requireJSONFile = function(file, opts) {
      return this.parseJSONFile(file, opts);
    };

    CSON.prototype.requireCSONFile = function(file, opts) {
      return this.parseCSONFile(file, opts);
    };

    CSON.prototype.requireJSFile = function(file, opts) {
      var err;
      try {
        return requireFreshSafe(file);
      } catch (_error) {
        err = _error;
        return new Error(err);
      }
    };

    CSON.prototype.requireCSFile = function(file, opts) {
      var err;
      require('coffee-script/register');
      try {
        return requireFreshSafe(file);
      } catch (_error) {
        err = _error;
        return new Error(err);
      }
    };

    return CSON;

  })();

  module.exports = new CSON();

}).call(this);
