var assert = require('assert')
var base58check = require('./base58check')
var networks = require('./networks')

function findScriptTypeByVersion(queryVersion) {
  for (var networkName in networks) {
    var network = networks[networkName]

    for (var versionName in network) {
      var version = network[versionName]

      if (version === queryVersion) {
        return versionName
      }
    }
  }

  throw new Error('Version has no corresponding network')
}

function Address(hash, version) {
  assert(Buffer.isBuffer(hash), 'First argument must be a Buffer')
  assert.strictEqual(hash.length, 20, 'Invalid hash length')
  assert.strictEqual(version & 0xFF, version, 'Invalid version byte')

  this.hash = hash
  this.version = version
}

// Import functions
Address.fromBase58Check = function(string) {
  var decode = base58check.decode(string)

  return new Address(decode.payload, decode.version)
}

Address.fromScriptPubKey = function(script, network) {
  network = network || networks.bitcoin

  var type = script.getOutType()

  // Pay-to-pubKeyHash
  if (type === 'pubkeyhash') {
    return new Address(new Buffer(script.chunks[2]), network.pubKeyHash)
  }

  // Pay-to-scriptHash
  else if (type === 'scripthash') {
    return new Address(new Buffer(script.chunks[1]), network.scriptHash)
  }

  throw new Error('Could not derive address from script')
}

// Export functions
Address.prototype.toBase58Check = function () {
  return base58check.encode(this.hash, this.version)
}

Address.prototype.toScriptPubKey = function() {
  var scriptType = findScriptTypeByVersion(this.version)

  // Pay-to-pubKeyHash
  if (scriptType === 'pubKeyHash') {
    return Script.createPubKeyHashScriptPubKey(this.hash)
  }

  // Pay-to-scriptHash
  else if (scriptType === 'scriptHash') {
    return Script.createP2SHScriptPubKey(this.hash)
  }

  throw new Error('Address has no matching script')
}

Address.prototype.toString = Address.prototype.toBase58Check

module.exports = Address

// http://stackoverflow.com/a/14098262
var Script = require('./script')

@@ -400,67 +400,8 @@
 %0A  %7D
-%0A%0A  throw new Error('Version has no corresponding network')
 %0A%7D%0A%0A
@@ -680,16 +680,199 @@
 sion%0A%7D%0A%0A
+Address.Error = function(message) %7B%0A  this.name = 'AddressError'%0A  this.message = message%0A%7D%0AAddress.Error.prototype = new Error()%0AAddress.Error.prototype.constructor = Address.Error%0A%0A
 // Impor
@@ -1442,51 +1442,54 @@
 new 
-Error('Could not derive address from script
+Address.Error(type + ' has no matching Address
 ')%0A%7D
@@ -1981,22 +1981,30 @@
 new 
-Error('
 Address
+.Error(this + '
  has

use Address.Error instead