var AddressAnalyzer = (function() {
  var padLeft = function(r) {
    var r1 = r.slice();
    r1.unshift("");
    return r1;
  };
  var padRight = function(r) {
    var r1 = r.slice();
    r1.push("");
    return r1;
  };
  var padBoth = function(r) {
    var r1 = r.slice();
    r1.push("");
    r1.unshift("");
    return r1;
  };
  var none = function(r) {
    return r;
  };

  var postprocess = function(res) {
    if (/^(aleja|plac)$/.test(res[0])) {
      var x = res[0];
      res[0] = '';
      res[1] = x + ' ' + res[1];
    }
    return res;
  };

  var cleanup = function(s) {
    return s.trim().replace(/ul\.?\s+/, '', 'i')
      .replace(/[\s\b]+al\.?[\s\b]+/, ' aleja ', 'i')
      .replace(/[\s\b]+pl\.?[\s\b]+/, ' plac ', 'i')
      .replace(/^al\.?[\s\b]+/, 'aleja ', 'i')
      .replace(/^pl\.?[\s\b]+/, 'plac ', 'i')
      .replace('  ', ' ', 'i')
      .replace('  ', ' ', 'i')
      .replace('  ', ' ', 'i')
      .toLowerCase();
  };

  var compare = function(a, b) {
    var r = a.length == b.length;
    var i = 0;
    while (r && i < a.length) {
      r = r && (a[i] == b[i]);
      i++;
    }
    return r;
  };

  var rx = [];
  rx[0] = [/^\s*(\D+?)[\s,]+(.+?)[\s,]+(\d+\S*)\s*$/, none];
  rx[1] = [/^\s*(\D+?)[\s,]+(\d+\S*)\s*$/, padLeft];
  rx[2] = [/^\s*(\D+?)\s*,+\s*(\D+)\s*$/, padRight];
  rx[3] = [/^\s*(\D+[\s\D]+)\s*$/, padBoth];
  rx[4] = [/^\s*(.+?)[\s,]+(\d+\S*)\s*$/, padLeft];

  return {'analyze': function(str)
          {
            for (var j = 0; j < rx.length; j++) {
              var res = rx[j][0].exec(cleanup(str));
              if (res) {
                res.shift()
                var after = rx[j][1];
                res = postprocess(after(res));
                return res;
              }
            }
            return ["", cleanup(str), ""];
          }
         };

}());


var AddressAnalyzer_test = function() {
  var test = [["Kraków, Krucza 1",			["kraków", "krucza", "1"]],
              ["Kraków, Krucza, 1",			["kraków", "krucza", "1"]],
              ["Kraków krucza 1",			["kraków", "krucza", "1"]],
              ["krucza 1",				["", "krucza", "1"]],
              ["Krucza",				["", "krucza", ""]],
              ["Kraków Krucza",			["kraków", "krucza", ""]],
              ["Kraków, Krucza",			["kraków", "krucza", ""]],
              ["kraków, aleje jerozolimskie",	["kraków", "aleje jerozolimskie", ""]],
              ["kraków, aleje jerozolimskie 138a",	["kraków", "aleje jerozolimskie", "138a"]],
              ["kraków, 3 maja 138a",		["kraków", "3 maja", "138a"]],
              ["3 maja 54/35",			["", "3 maja", "54/35"]],
              ["3 maja, 3",				["", "3 maja", "3"]],
              ["bitwy warszawskiej",			["", "bitwy warszawskiej", ""]],
              ["bitwy warszawskiej 1920",		["", "bitwy warszawskiej 1920", ""]],
              ["bitwy warszawskiej 1920, 59a",	["", "bitwy warszawskiej 1920", "59a"]],

              ["Kraków, al. Krucza 1",		["kraków", "aleja krucza", "1"]],
              ["Kraków, al. Krucza, 1",		["kraków", "aleja krucza", "1"]],
              ["Kraków al. krucza 1",		["kraków", "aleja krucza", "1"]],
              ["al. krucza 1",			["", "aleja krucza", "1"]],
              ["al. Krucza",				["", "aleja krucza", ""]],
              ["Kraków al. Krucza",			["kraków", "aleja krucza", ""]],
              ["Kraków, al. Krucza",			["kraków", "aleja krucza", ""]],
              ["kraków, al. jerozolimskie 138a",	["kraków", "aleja jerozolimskie", "138a"]],
              ["kraków, aleje jerozolimskie 138a",	["kraków", "aleje jerozolimskie", "138a"]],
              ["kraków, al. 3 maja 138a",		["kraków", "aleja 3 maja", "138a"]],
              ["al. 3 maja 54/35",			["", "aleja 3 maja", "54/35"]],
              ["al. 3 maja, 3",			["", "aleja 3 maja", "3"]],
              ["al. bitwy warszawskiej",		["", "aleja bitwy warszawskiej", ""]],
              ["al. bitwy warszawskiej 1920",	["", "aleja bitwy warszawskiej 1920", ""]],
              ["al. bitwy warszawskiej 1920 59a",	["", "aleja bitwy warszawskiej 1920", "59a"]],
              ["al. bitwy warszawskiej 1920, 59a",	["", "aleja bitwy warszawskiej 1920", "59a"]],
              ["warszawskiej 1920 59",		["", "warszawskiej 1920", "59"]],

              ["Kraków, ul. Krucza 1",		["kraków", "krucza", "1"]],
              ["Kraków, ul. Krucza, 1",		["kraków", "krucza", "1"]],
              ["Kraków ul. krucza 1",		["kraków", "krucza", "1"]],
              ["ul. krucza 1",			["", "krucza", "1"]],
              ["ul. Krucza",				["", "krucza", ""]],
              ["Kraków ul. Krucza",			["kraków", "krucza", ""]],
              ["Kraków, ul. Krucza",			["kraków", "krucza", ""]],
              ["kraków, aleje jerozolimskie 138a",	["kraków", "aleje jerozolimskie", "138a"]],
              ["kraków, ul. 3 maja 138a",		["kraków", "3 maja", "138a"]],
              ["ul. 3 maja 54/35",			["", "3 maja", "54/35"]],
              ["ul. 3 maja, 3",			["", "3 maja", "3"]],
              ["ul. bitwy warszawskiej",		["", "bitwy warszawskiej", ""]],
              ["plac bitwy warszawskiej 1920, 45a",	["", "plac bitwy warszawskiej 1920", "45a"]],
              ["bitwy warszawskiej 1920, plac, 45a",	["", "bitwy warszawskiej 1920, plac", "451"]],
              ["bitwy warszawskiej 1920 plac, 45a",	["", "bitwy warszawskiej 1920 plac", "45a"]],
              ["bitwy warszawskiej 1920 pl. 45a",	["", "bitwy warszawskiej plac", "45a"]],
              ["plac bitwy warszawskiej 1920",	["", "plac bitwy warszawskiej 1920", ""]],
              ["ul. bitwy warszawskiej 1920, 59a",	["", "bitwy warszawskiej 1920", "59a"]],
             ];

  var print = function() {
    for (var i = 0; i < test.length; i++) {
      console.log(test[i][0], '   -   ', cleanup(test[i][0]), '   -   ', test[i][1]);
    }
  }

  var success = 0;
  for (var i = 0; i < test.length; i++) {
    res = AddressAnalyzer.analyze(test[i][0]);
    var cmp = compare(res, test[i][1]);
    if (cmp)
      success++;
  };
  console.log(success, 'of', test.length, 'successful');
};

