function Country(name, code, cin_form, abi_form, cab_form, acc_form)
{
  this.name      =name;
  this.code      = code;
  this.cin       = Country_decode_format(cin_form);
  this.abi       = Country_decode_format(abi_form);
  this.cab       = Country_decode_format(cab_form);  
  this.acc       = Country_decode_format(acc_form);
  this.cin_lng   = Country_calc_length(this.cin);
  this.abi_lng   = Country_calc_length(this.abi);
  this.cab_lng   = Country_calc_length(this.cab);
  this.acc_lng   = Country_calc_length(this.acc);
  this.total_lng = 4 + this.cin_lng + this.abi_lng + this.cab_lng + this.acc_lng;
}

function Country_decode_format(form)
{
  var form_list = new Array();
  var parts = form.split(" ");
  for (var i = 0; i < parts.length; ++i)
  {
    var part = parts[i];
    if (part != "")
    {
      var typ = part.charAt(part.length - 1);
      if (typ == "a" || typ == "n")
        part = part.substring(0, part.length - 1);
      else
        typ = "c";
      var lng = parseInt(part);
      form_list[form_list.length] = new Array(lng, typ);
    }
  }
  return form_list;
}

function Country_calc_length(form_list)
{
  var sum = 0;
  for (var i = 0; i < form_list.length; ++i)
    sum += form_list[i][0];
  return sum;
}

var iban_data = new Array(
  new Country("Italia",         "IT", "1a","5n","5n","0  12   0 "),
  new Country("San Marino",     "SM", "1a","5n","5n","0  12   0 "));

// Search the country code in the iban_data list.
function CountryData(code)
{
  for (var i = 0; i < iban_data.length; ++i)
    if (iban_data[i].code == code)
      return iban_data[i];
  return null;
}

function mod97(digit_string)
{
  var m = 0;
  for (var i = 0; i < digit_string.length; ++i)
    m = (m * 10 + parseInt(digit_string.charAt(i))) % 97;
  return m;
}

function capital2digits(ch)
{
  var capitals = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  for (var i = 0; i < capitals.length; ++i)
    if (ch == capitals.charAt(i))
      break;
  return i + 10;
}

function fill0(s, l)
{
  while (s.length < l)
    s = "0" + s;
  return s.toUpperCase();
}

function strcmp(s1, s2)
{
  var chars = "AaÄäBbCcDdEeFfGgHhIiJjKkLlMmNnOoÖöPpQqRrSsßTtUuÜüVvWwXxYyZz";
  var lng = (s1.length < s2.length) ? s1.length : s2.length;
  for (var i = 0; i < lng; ++i)
  {
    var d = chars.indexOf(s1.charAt(i)) - chars.indexOf(s2.charAt(i));
    if (d != 0)
      return d;
  }
  return s1.length - s2.length;
}

function CountryIndexTable()
{
  var tab = new Array();
  var i, j, t;
  for (i = 0; i < iban_data.length; ++i)
    tab[i] = i;
  for (i = tab.length - 1; i > 0; --i)
    for (j = 0; j < i; ++j)
      if (strcmp(iban_data[tab[j]].name, iban_data[tab[j+1]].name) > 0)
        t = tab[j], tab[j] = tab[j+1], tab[j+1] = t;
  return tab;
}

function ChecksumIBAN(iban)
{
  var code     = iban.substring(0, 2);
  var checksum = iban.substring(2, 4);
  var bban     = iban.substring(4);

  var digits = "";
  for (var i = 0; i < bban.length; ++i)
  {
    var ch = bban.charAt(i).toUpperCase();
    if ("0" <= ch && ch <= "9")
      digits += ch;
    else
      digits += capital2digits(ch);
  }
  for (var i = 0; i < code.length; ++i)
  {
    var ch = code.charAt(i);
    digits += capital2digits(ch);
  }
  digits += checksum;

  checksum = 98 - mod97(digits);
  return fill0("" + checksum, 2);
}

function FillAccount(country, account)
{
  return fill0(account, country.acc_lng).toUpperCase();
}

function InvalidPart(form_list, iban_part)
{
  for (var f = 0; f < form_list.length; ++f)
  {
    var lng = form_list[f][0], typ = form_list[f][1];
    if (lng > iban_part.length)
      lng = iban_part.length;
    for (var i = 0; i < lng; ++i)
    {
      var ch = iban_part.charAt(i);
      var a = ("A" <= ch && ch <= "Z");
      var n = ("0" <= ch && ch <= "9");
      var c = n || a || ("a" <= ch && ch <= "z");
      if ((!c && typ == "c") || (!a && typ == "a") || (!n && typ == "n"))
        return true;
    }
    iban_part = iban_part.substring(lng);
  }
  return false;
}


function InvalidAbiLength(country, abi)
{
  return (abi.length != country.abi_lng);
}


function InvalidCabLength(country, cab)
{
  return (cab.length != country.cab_lng);
}

function InvalidAbi(country, abi)
{
  return (InvalidAbiLength(country, abi) ||
          InvalidPart(country.abi, abi));
}

function InvalidCab(country, cab)
{
  return (InvalidCabLength(country, cab) ||
          InvalidPart(country.cab, cab));
}

function InvalidAccountLength(country, account)
{
  return (account.length < 1 || account.length > country.acc_lng);
}

function InvalidAccount(country, account)
{
  return (InvalidAccountLength(country, account) ||
          InvalidPart(country.acc, FillAccount(country, account)));
}

function InvalidIBANlength(country, iban)
{
  return (iban.length != country.total_lng);
}

function extern(intern)
{
  var s = "IBAN";
  for (var i = 0; i < intern.length; ++i)
  {
    if (i % 4 == 0)
      s += " ";
    s += intern.charAt(i);
  }
  return s;
}

function intern(extern)
{
  if (extern.substring(0, 4) == "IBAN")
    extern = extern.substring(4);
  var s = "";
  for (var i = 0; i < extern.length; ++i)
    if (extern.charAt(i) != " ")
      s += extern.charAt(i);
  return s;
}

function CalcIBAN(country, cin, abi, cab, account)
{
  var fill_acc = FillAccount(country, account);
  var checksum = ChecksumIBAN(country.code + "00" + cin + abi + cab + fill_acc);
  return country.code + checksum + cin + abi + cab + fill_acc;
}

function CalcAltIBAN(country, cin, abi, cab, account)
{
  var fill_acc = FillAccount(country, account);
  var checksum = ChecksumIBAN(country.code + "00" + cin + abi + cab + fill_acc);
  checksum = fill0("" + mod97(checksum), 2);
  return country.code + checksum + cin + abi + cab + fill_acc;
}

function IBANokay(iban)
{
  return ChecksumIBAN(iban) == "97";
}

function CreateIBAN()
{
  var form = document.ibanform;
  var code = form.country.options[form.country.selectedIndex].value;
  var cin  = CalcCIN(form.abi.value + form.cab.value + fill0(intern(form.account.value),12));
  var abi  = intern(form.abi.value);
  var cab  = intern(form.cab.value);
  var account = intern(form.account.value).toUpperCase();
  var country = CountryData(code);
  var txtCountry =  "";
  if (country == null) txtCountry="";
  else if(country.name=="Italia") txtCountry="l'Italia"; else txtCountry=country.name;

  var err = null, err_focus = null, form_error=null;
  if (country == null)
  {
	err = _("Seleziona il Paese");
    document.getElementById('abi').style.backgroundColor = "#FFFFFF";
    document.getElementById('cab').style.backgroundColor = "#FFFFFF";
    document.getElementById('account').style.backgroundColor = "#FFFFFF";
    err_focus = form.country;
  }
  else if (InvalidAbiLength(country, abi))
  {
    err = _("Il codice Abi inserito non ha la lunghezza (") + abi.length +
          _(") valida per ") + txtCountry +
          " (" + country.abi_lng + ")";
    err_focus = form.abi;
    document.getElementById('abi').style.backgroundColor = "#FF0000";
    document.getElementById('cab').style.backgroundColor = "#FFFFFF";
    document.getElementById('account').style.backgroundColor = "#FFFFFF";
  }
  else if (InvalidAbi(country, abi))
  {
    err = _("Il codice Abi inserito (") + abi + _(") non ha un formato valido per ") +
          txtCountry;
    err_focus = form.abi;
    document.getElementById('abi').style.backgroundColor = "#FF0000";
    document.getElementById('cab').style.backgroundColor = "#FFFFFF";
    document.getElementById('account').style.backgroundColor = "#FFFFFF";
  }
    else if (InvalidCabLength(country, cab))
  {
    err = _("Il codice Cab inserito non ha la lunghezza (") + cab.length +
          _(") valida per ") + txtCountry +
          " (" + country.cab_lng + ")";
    err_focus = form.cab;
    document.getElementById('abi').style.backgroundColor = "#FFFFFF";
    document.getElementById('cab').style.backgroundColor = "#FF0000";
    document.getElementById('account').style.backgroundColor = "#FFFFFF";
  }
  else if (InvalidCab(country, cab))
  {
    err = _("Il codice Cab inserito (") + cab + _(") non ha un formato valido per ") +
          txtCountry;
    err_focus = form.cab;
    document.getElementById('abi').style.backgroundColor = "#FFFFFF";
    document.getElementById('cab').style.backgroundColor = "#FF0000";
    document.getElementById('account').style.backgroundColor = "#FFFFFF";
  }
  else if (InvalidAccountLength(country, account))
  {
    err = _("Il numero di conto corrente inserito non ha la lunghezza (") + account.length +
          _(") valida per ") + txtCountry +
          " (" + country.acc_lng + ")";
    err_focus = form.account;
    document.getElementById('abi').style.backgroundColor = "#FFFFFF";
    document.getElementById('cab').style.backgroundColor = "#FFFFFF";
    document.getElementById('account').style.backgroundColor = "#FF0000";
  }
  else if (InvalidAccount(country, account))
  {
    err = _("Il numero di conto corrente inserito (") + account + _(") non ha un formato valido per ") +
          txtCountry;
    err_focus = form.account;
    document.getElementById('abi').style.backgroundColor = "#FFFFFF";
    document.getElementById('cab').style.backgroundColor = "#FFFFFF";
    document.getElementById('account').style.backgroundColor = "#FF0000";
  }

  if (err)
  {  
	document.getElementById("stampa").innerHTML="&nbsp;&nbsp;&bull;&nbsp;&nbsp;<strong>Stampa</strong>";
	document.getElementById("ibanstampa").innerHTML="";
	document.getElementById("ibanelettro").innerHTML="";
	document.getElementById("ibanalt").innerHTML="";
    err_focus.focus();
    alert(err);
  }
  else
  {
	form.abi.value = abi;
	form.cab.value=cab;
    form.account.value = FillAccount(country, account);
	form.cin.value=cin;
	
	var ibanelektro = extern(CalcIBAN(country, cin, abi, cab, account));
	var ibanelektro = ibanelektro.substring(5)
	var ibanelektro_array = ibanelektro.split(" ");
	var neuer_ibanelektro = ibanelektro_array.join("");

	document.getElementById('abi').style.backgroundColor = "#FFFFFF";
    document.getElementById('cab').style.backgroundColor = "#FFFFFF";
    document.getElementById('account').style.backgroundColor = "#FFFFFF";
	
document.getElementById("ibanstampa").innerHTML="&nbsp;Iban per la stampa:<input name=\"iban\" type=\"text\" size=\"50\" maxlength=\"60\" style=\"height:14px;font-weight:bold; font-family:tahoma; font-size:12px; background-color:#DEE0CC; border:1px solid #DEE0CC\">";
   	form.iban.value = extern(CalcIBAN(country, cin, abi, cab, account));
document.getElementById("ibanelettro").innerHTML="&nbsp;Iban elettronico:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input name=\"iban2\" type=\"text\" size=\"50\" maxlength=\"60\" style=\"height:14px;font-weight:bold;font-family:tahoma; font-size:12px; background-color:#DEE0CC; border:1px solid #DEE0CC\">";
	form.iban2.value = neuer_ibanelektro;	 
	form.check.value=form.iban2.value.substring(2, 4);
    var alt_iban = extern(CalcAltIBAN(country, cin, abi, cab, account));
    if (alt_iban != form.iban.value)
	{var alt_iban=alt_iban.substring(5);
	 var alt_iban_array=alt_iban.split(" ");
 	 var n_alt_iban=alt_iban_array.join("");
	 
document.getElementById("ibanalt").innerHTML="<textarea name=\"txt_iban_alt\" cols=\"90\" rows=\"2\" readonly=\"readonly\" wrap=\"physical\" id=\"txt_iban_alt\" style=\"overflow:hidden; font-family:tahoma; font-size:11px; background-color:#DEE0CC; border-style:none; padding-left:3px\"></textarea>";
	 form.txt_iban_alt.value="Attenzione: per le coordinate indicate e' possibile calcolare anche un altro Iban formalmente corretto: "+ n_alt_iban + ". Informarsi presso la banca.";	
	}
	else
	{
	document.getElementById("ibanalt").innerHTML="";
    var alt_iban = "";
	var n_alt_iban = "";
	var n_iban_alt="";
	}
    if (debug_output)
      debug_check_vars();
document.getElementById("stampa").innerHTML="&nbsp;&nbsp;&bull;&nbsp;&nbsp;<a href=\"printIban.php?country="+form.country.value+"&check="+form.check.value+"&cin="+cin+"&abi="+abi+"&cab="+cab+"&account="+form.account.value+"&iban="+form.iban.value+"&iban2="+form.iban2.value+"\"onclick=\"popUp(this.href,'console',190,370);return false;\" target=\"newWin\"><strong>Stampa</strong></a>";
  }
}
function CheckIBAN()
{
  var form = document.ibanform;
  var iban = intern(form.iban.value);

  var code     = iban.substring(0, 2);
  var checksum = iban.substring(2, 4);
  var bban     = iban.substring(4);
  var country  = CountryData(code);

  var err = null;
  if (country == null)
    err = _("Il codice Paese non e' presente");
  else if (InvalidIBANlength(country, iban))
    err = _("La lunghezza del codice Iban inserito (") + iban.length + _(") non e' corretta");
  else
  {
    var abi_lng = country.abi_lng;
	var cab_lng = country.cab_lng;
    var mycin	= bban.substring(0,1);
	var abi     = bban.substring(1, abi_lng+1);
	var cab     = bban.substring(abi_lng+1, abi_lng+cab_lng+1);
    var account = bban.substring(abi_lng+cab_lng+1);
	var cin     = CalcCIN(abi + cab + account);
	
  var txtCountry =  "";
  if (country == null) txtCountry="";
  else if(country.name=="Italia") txtCountry="l'Italia"; else txtCountry=country.name;
  
    if (InvalidAbi(country, abi))
      err = _("Il codice Abi (") + abi + _(") non ha un formato valido per ") +
            txtCountry;
    else if (InvalidCab(country, cab))
      err = _("Il codice Cab (") + cab + _(") non ha un formato valido per ") +
            txtCountry;
    else if (InvalidAccount(country, account))
      err = _("Account Number ") + account + _(" is not correct for ") +
            country.name;
	else if (mycin!=cin)
	  err=  _("Il codice Cin (") + mycin + _(") non corrisponde a quello corretto (") +
			cin + ")";
    else if (!IBANokay(iban))
      err = _("Le cifre di controllo (") + checksum + _(") potrebbero non essere corrette");
  }

  if (err)
  {
    form.country.selectedIndex = 0;
    form.abi.value = "";
    form.account.value = "";
    form.alt_iban.value = "";
    form.iban.focus();

    alert(err);
  }
  else
  {
    form.iban.value = extern(iban);
    for (var i = form.country.options.length - 1; i > 0; --i)
      if (form.country.options[i].value == code)
        break;
    form.country.selectedIndex = i;
    form.abi.value = abi;
	form.cab.value = cab;
    form.account.value = account;
	
    form.alt_iban.value = extern(CalcAltIBAN(country, cin, abi, cab, account));
    if (form.alt_iban.value != form.iban.value)
      form.alt_iban.value += " (*)";
    else
      form.alt_iban.value = "";

    if (debug_output)
      debug_check_vars();
  }
}

function WriteCountrySelectionBar()
{
  document.write('<select name="country" size="1" style="font-family:tahoma; font-size:11px; color:#293B43; border:1px solid #A7A7A7">');
  document.write('<option value="??">&nbsp;</option>');
  var tab = CountryIndexTable();
  for (var i = 0; i < tab.length; ++i)
  {
    var country = iban_data[tab[i]];
    document.write('<option value="' + country.code + '">' +
                   country.name + ' (' + country.code + ')</option>');
  }
  document.write('</select>');
}

function debug_check_vars()
{
  var o = false;
  var s = "";
  for (var v in window)
  {
    if (o)
      s += "" + v + "=" + window[v] + "\n";
    if (v == "debug_check_vars")
      o = true;
  }
  if (s != "")
    alert("vars:\n" + s);
  else
    alert("no vars");
}
function CalcCIN(ABICABConto){
var form = document.ibanform;
cc=form.abi.value + form.cab.value + fill0(intern(form.account.value),12);
aa="A0B1C2D3E4F5G6H7I8J9K#L#M#N#O#P#Q#R#S#T#U#V#W#X#Y#Z#-#.# #";
bb="B1A0K#P#L#C2Q#D3R#E4V#O#S#F5T#G6U#H7M#I8N#J9W#Z#Y#X# #-#.#";
dd=0;
tabella="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
for(var ii=1;ii<22;ii+=2)
{
d1=aa.indexOf(cc.charAt(ii));
dd=dd+Math.floor(d1/2);
}
 
for(var ii=0;ii<22;ii+=2)
{
d1=bb.indexOf(cc.charAt(ii));
dd=dd+Math.floor(d1/2);
}
 
dd=dd-(Math.floor(dd/26)*26);
 
return aa.charAt(dd*2);
}

var debug_output = (location.href.charAt(location.href.length - 1) == "#") ||
                   (location.href.charAt(location.href.length - 1) == "?");

if (debug_output)
  debug_iban_data();

function debug_iban_data()
{
  var s = "";
  for (var i = 0; i < iban_data.length; ++i)
  {
    var country = iban_data[i];
    s += country.name + " / " + country.code + " / ";
    for (var f = 0; f < country.bank.length; ++f)
      s += country.bank[f][0] + country.bank[f][1];
    s += " = " + country.bank_lng + " / ";
    for (var f = 0; f < country.acc.length; ++f)
      s += country.acc[f][0] + country.acc[f][1];
    s += " = " + country.acc_lng + " / " + country.total_lng + "\n";
  }
  alert(s);
}

var trans_tab = new Array();

function _(s)
{
  var t = trans_tab[s];
  if (t)
    s = t;
  return s;
}

function CancIBAN()
{
var form = document.ibanform;
form.reset();
document.getElementById('abi').style.backgroundColor = "#FFFFFF";
document.getElementById('cab').style.backgroundColor = "#FFFFFF";
document.getElementById('account').style.backgroundColor = "#FFFFFF";
document.getElementById("stampa").innerHTML="&nbsp;&nbsp;&bull;&nbsp;&nbsp;<strong>Stampa</strong>";
document.getElementById("ibanstampa").innerHTML="";
document.getElementById("ibanelettro").innerHTML="";
document.getElementById("ibanalt").innerHTML="";
}
