//docs.google.com/presentation/d/1XgKaFEgPIzF2psVgY62-KnylV81gsjCWu999h4QtaOE/
var fs = require('fs');

var glob = require('glob');

glob('geoJson/*.json', {}, function (err, files) {
  files.forEach(function (file) {
    var output = '../' + file.replace('.json', '.js');
    var rawStr = fs.readFileSync(file, 'utf8');
    var json = JSON.parse(rawStr);
    console.log(output); // Meta tag

    json.UTF8Encoding = true;
    var features = json.features;

    if (!features) {
      return;
    }

    features.forEach(function (feature) {
      var encodeOffsets = feature.geometry.encodeOffsets = [];
      var coordinates = feature.geometry.coordinates;

      if (feature.geometry.type === 'Polygon') {
        coordinates.forEach(function (coordinate, idx) {
          coordinates[idx] = encodePolygon(coordinate, encodeOffsets[idx] = []);
        });
      } else if (feature.geometry.type === 'MultiPolygon') {
        coordinates.forEach(function (polygon, idx1) {
          encodeOffsets[idx1] = [];
          polygon.forEach(function (coordinate, idx2) {
            coordinates[idx1][idx2] = encodePolygon(coordinate, encodeOffsets[idx1][idx2] = []);
          });
        });
      }
    });
    fs.writeFileSync(output, addAMDWrapper(JSON.stringify(json)), 'utf8');
  });
});

function encodePolygon(coordinate, encodeOffsets) {
  var result = '';
  var prevX = quantize(coordinate[0][0]);
  var prevY = quantize(coordinate[0][1]); // Store the origin offset

  encodeOffsets[0] = prevX;
  encodeOffsets[1] = prevY;

  for (var i = 0; i < coordinate.length; i++) {
    var point = coordinate[i];
    result += encode(point[0], prevX);
    result += encode(point[1], prevY);
    prevX = quantize(point[0]);
    prevY = quantize(point[1]);
  }

  return result;
}

function addAMDWrapper(jsonStr) {
  return ['define(function() {', '    return ' + jsonStr + ';', '});'].join('\n');
}

function encode(val, prev) {
  // Quantization
  val = quantize(val); // var tmp = val;
  // Delta

  val = val - prev;

  if ((val << 1 ^ val >> 15) + 64 === 8232) {
    //WTF, 8232 will get syntax error in js code
    val--;
  } // ZigZag


  val = val << 1 ^ val >> 15; // add offset and get unicode

  return String.fromCharCode(val + 64); // var tmp = {'tmp' : str};
  // try{
  //     eval("(" + JSON.stringify(tmp) + ")");
  // }catch(e) {
  //     console.log(val + 64);
  // }
}

function quantize(val) {
  return Math.ceil(val * 1024);
}