var fs = require('fs'),
  http = require('http')

var async = require('async'),
  rimraf = require('rimraf'),
  shp = require('shpjs')

var indexGeoJSON = require('./createGeoIndex.js')

var MASTER_DL_URL = 'http://efele.net/maps/tz/world/tz_world_mp.zip',
  MASTER_DL_SHA_URL = 'http://efele.net/maps/tz/world/tz_world_mp.zip.sha1'

/**
 * Copied from http://stackoverflow.com/a/12101012/269834
 */
var toArrayBuffer = function(buffer) {
  var ab = new ArrayBuffer(buffer.length)
  var view = new Uint8Array(ab)
  for (var i = 0; i < buffer.length; ++i) {
    view[i] = buffer[i]
  }
  return view
}

var extractToGeoJson = function(callback) {
  shp(toArrayBuffer(fs.readFileSync('./downloads/tz_shp.zip')))
    .then(function(geojson) { callback(null, geojson) })
    .catch(function(e){ callback(e) })
}

var downloadFile = function(url, rename, callback) {
  var dlFile = 'downloads/' + rename
  console.log('Downloading', url)
  async.auto({
    rm: function(cb) {
      rimraf(dlFile, cb)
    },
    dl: ['rm', function(results, cb) {
      var file = fs.createWriteStream(dlFile)
      http.get(url, function(response) {
        response.pipe(file)
        file.on('finish', function() {
          file.close(cb)
        })
      }).on('error', cb)
    }]
  }, callback)
  
}

var makeReadShaFileFn = function(filename) {
  return function(results, cb) {
    fs.readFile(filename, 'utf-8', cb ? cb : results)
  }
}

module.exports = function(cfg, callback) {

  var mainUrl, shaUrl, dataDir, masterLocalShaFile

  if(!callback) {
    if(typeof cfg === 'function') {
      callback = cfg
    } else {
      callback = function() {}
    }

    mainUrl = MASTER_DL_URL
    shaUrl = MASTER_DL_SHA_URL

  } else {
    mainUrl = cfg.mainUrl || MASTER_DL_URL
    shaUrl = cfg.shaUrl || MASTER_DL_SHA_URL
  }

  dataDir = cfg.dataDir || './data'
  masterLocalShaFile = dataDir + '/tz_world_mp.zip.sha1'

  async.auto({
    // download sha file to see if master file is updated
    downloadSha: function(cb) {
      downloadFile(shaUrl, 'file.sha1', cb)
    },
    // read local sha file
    readLocalSha: makeReadShaFileFn(masterLocalShaFile),
    // read downloaded sha file
    readDownloadedSha: ['downloadSha', makeReadShaFileFn('./downloads/file.sha1')],
    comparseShaFiles: ['readLocalSha', 'readDownloadedSha', function(results, cb) {
      if(results.readLocalSha === results.readDownloadedSha) {
        var message = 'remote file same as local, no need to download'
        console.log(message)
        return cb(message)
      } 
      cb()
    }],
    unlinkLocalShaFile: ['comparseShaFiles', function(results, cb) {
      fs.unlink(masterLocalShaFile, cb)
    }],
    updateShaFile: ['unlinkLocalShaFile', function(results, cb) {
      fs.rename('./downloads/file.sha1', masterLocalShaFile, cb)
    }],
    deleteIndexFoldersAndFiles: ['comparseShaFiles', function(results, cb) {
      async.each(['a', 'b', 'c', 'd', 'index.json'], function(fileOrFolder, eachCb) {
        rimraf(dataDir + '/' + fileOrFolder, eachCb)
      }, cb)
    }],
    downloadShapefile: ['comparseShaFiles', function(results, cb) {
      downloadFile(mainUrl, 'tz_shp.zip', cb)
    }],
    extractShapefileToGeoJSON: ['downloadShapefile', function(results, cb) {
      extractToGeoJson(cb)
    }],
    createIndex: ['deleteIndexFoldersAndFiles', 'extractShapefileToGeoJSON', function(results, cb) {
      indexGeoJSON(results.extractShapefileToGeoJSON, dataDir, 0.5, cb)
    }]

  }, function(err, results) {
    if(err && err !== 'remote file same as local, no need to download') {
      return callback(err)
    }
    callback()
  })

}
@@ -73,16 +73,46 @@
 sync'),%0A
+  mkdirp = require('mkdirp'),%0A
   rimraf
@@ -1022,24 +1022,104 @@
  cb)%0A    %7D,%0A
+    mkdir: %5B'rm', function(results, cb) %7B%0A      mkdirp('downloads', cb)%0A    %7D%5D,%0A
     dl: %5B'rm
@@ -1112,26 +1112,29 @@
 ,%0A    dl: %5B'
-r
 m
+kdir
 ', function(

Create downloads folder if not existing