﻿// letters will be replaced with digits
repl = new Array (	"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
			"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
		 	"10","11","12","13","14","15","16","17","18","19","20","21","22",
		 	"23","24","25","26","27","28","29","30","31","32","33","34","35");
// we have currently 3 languages   1 english, 2 russian, 3 latvian
lgc = 1;
// country codes, fixed length for those countries, appliance of EU REGULATION 2560/2001 and IBAN example
ilbc = new Array (	"AD","AT","BA","BE","BG","CH","CS","CY","CZ","DE","DK","EE","ES","FI","FO","FR","GB","GI","GL","GR",
			"HR","HU","IE","IS","IT","LI","LT","LU","LV","MC","MK","MT","MU","NL","NO","PL","PT","RO","SE","SI",
			"SK","SM","TN","TR",
			 24,  20,  20,  16,  22,  21,  22,  28,  24,  22,  18,  20,  24,  18,  18,  27,  22,  23,  18,  27,
			 21,  28,  22,  26,  27,  21,  20,  20,  21,  27,  19,  31,  30,  18,  15,  28,  25,  24,  24,  19,
			 24,  27,  24,  26,
			"n", "y", "n", "y", "n", "n", "n", "y", "y", "y", "y", "y", "y", "y", "n", "y", "y", "y", "n", "y",
			"n", "y", "y", "y", "y", "y", "y", "y", "y", "n", "n", "y", "n", "y", "y", "y", "y", "n", "y", "y",
			"y", "n", "n", "n",
			"AD1200012030200359100100","AT611904300234573201","BA391290079401028494","BE68539007547034",
			"BG80BNBG96611020345678","CH9300762011623852957","CS73260005601001611379","CY17002001280000001200527600",
			"CZ6508000000192000145399","DE89370400440532013000","DK5000400440116243","EE382200221020145685",
			"ES9121000418450200051332","FI2112345600000785","FO7630004440960235","FR1420041010050500013M02606",
			"GB29NWBK60161331926819","GI75NWBK000000007099453","GL4330003330229543","GR1601101250000000012300695",
			
			"HR1210010051863000160","HU42117730161111101800000000","IE29AIBK93115212345678","IS140159260076545510730339",
			"IT60X0542811101000000123456","LI21088100002324013AA","LT121000011101001000","LU280019400644750000",
			"LV80BANK0000435195001","MC...","MK07300000000042425","MT84MALT011000012345MTLCAST001S",
			"MU17BOMM0101101030300200000MUR","NL91ABNA0417164300","NO9386011117947","PL27114020040000300201355387",
			"PT50000201231234567890154","RO49AAAA1B31007593840000","SE3550000000054910000003","SI56191000000123438",
			
			"SK3112000000198742637541","SM59Z0322509800000001400123","TN5914207207100707129648","TR330006100519786457841326");
// we have currently # countries
ctcnt = ilbc.length/4;
// we have currently # alert texts
atcnt = 10;
// we have currently # web texts
wbcnt = 10;

function $(id) {
	return document.getElementById(id);
}

// gets the country name 
function rcty(tnum) {
	return ctynm[tnum + ctcnt * (lngg - 1)];
}
//gets the error text
function ralt(tnum) {
	return altxt[tnum + atcnt * (lngg - 1)];
}
// the magic core routine
function checkibancore(iban) {
	illegal = /\W|_/; // contains chars other than (a-zA-Z0-9)
	if (illegal.test(iban)) $('ibanResult').innerHTML = ralt(0) +'<br /><br />'; // yes, alert and exit
	else { // no, continue
		illegal = /^\D\D\d\d.+/; // first chars are letter letter digit digit
		if (illegal.test(iban) == false) {
			$('ibanResult').innerHTML = ralt(1) +'<br /><br />'; // no, alert and exit
			return;
		} else { // yes, continue
			illegal = /^\D\D00.+|^\D\D01.+|^\D\D99.+/; // check digit are 00 or 01 or 99
			if (illegal.test(iban)) {
				$('ibanResult').innerHTML = ralt(2) +'<br /><br />'; // yes, alert and exit
				return;
			} else { // no, continue
				iban = iban.toUpperCase(); // uppercase, to ease
				cntry = iban.substr(0,2); // fetch country
				lofi = 6; // "default" length of IBAN
				for (i = 0; i < ctcnt; i++) {
					if (cntry == ilbc[i]) {
						lofi = ilbc[ctcnt+i];
						ctck = i;
					}
				}  // yes, country respected
				if (lofi == 6) { // no, alert
					$('ibanResult').innerHTML = (ralt(3)+cntry+ralt(4)) +'<br /><br />';
					lofi = iban.length;
					return;
				}  // but continue
				if ((iban.length-lofi) != 0) { // fits length to country
					$('ibanResult').innerHTML = (ralt(5) + rcty(ctck) + ralt(6) +' '+ ilbc[ctck+ctcnt] + ralt(7)) +'<br /><br />';
					return;
				} // no, alert and exit
				else { // yes, continue
					iban = iban.substr(4,lofi-4) + iban.substr(0,4); // country and check digits to the end
					for (i = 0; i <= 25; i++) { // replace letters with digits
						while (iban.search(repl[i])!= -1) iban = iban.replace(repl[i], repl[i+26]);
					} // all of them
					coss = Math.ceil(iban.length / 7); // calc count of substrings
					rmndr = ""; // remainer starts empty and always preceeds the current substring
					for (i = 1; i <= coss; i++) // step by step
						rmndr = String(parseFloat(rmndr+iban.substr((i-1)*7,7))%97); // modulo division 97
						
					return rmndr;
				}
			}
		}
	}
}

// perform the check
function checkiban(iban) {
	if (checkibancore(iban) == "1") $('ibanResult').innerHTML = ralt(8) +'<br /><br />'; // and prompt result
}

function rwt(tnum) { document.write(wptxt[(lngg-1)*wbcnt+tnum]); } //web page text by number
function rwt2(pos) { 
	if (wptxt[(lngg-1)*wbcnt] == pos) {
		document.write(" EU Regulation 2560/2001 "); }} //special web page text
// some convenience to list the countries
function rcc(tnum) { return ilbc[tnum]; } //country code by number
function rcn(tnum) { return rcty(tnum); } //country name by number
function rcr(tnum) { return ilbc[ctcnt*2+tnum]; } //country regulatory info by number
function rcl(tnum) { return wptxt[(lngg-1)*wbcnt+8]+ilbc[ctcnt*1+tnum]; } //hover text for code
function rce(tnum) { return wptxt[(lngg-1)*wbcnt+9]+ilbc[ctcnt*3+tnum]; } //hover text for name
// list countries in x columns with language y ##### old, use new please #####
function listcountries(columni,llngg) {
	listcountriesnew(columni,llngg,"n",""); }
// list countries in x columns with language y show flag y/n from path ##### new #####
// make sure the flag images are available at path and provide a style declaration like "img.tbg5cdf { height:20px; }" !!
function listcountriesnew(columni,llngg,flag,ipath) {
	lngg = llngg; //use language parameter
	if (flag == "n") {
		document.write("<table class=\"tbg5ct\">\r\n<TR class=\"tbg5crt\"><TD class=\"tbg5cdt\" colspan=\""+columni*2+"\"> </TD></TR>\r\n"); }
	else {	document.write("<table class=\"tbg5ct\">\r\n<TR class=\"tbg5crt\"><TD class=\"tbg5cdt\" colspan=\""+columni*3+"\"> </TD></TR>\r\n"); }
	numberofrows = Math.ceil(ctcnt/columni); //calculate rows
	for (i = 0; i < numberofrows; i++) { //for each row
		document.write("<tr class=\"tbg5crl\">");
		for (j = 0; j < columni; j++) { //for each column
			if ((i*columni+j)<ctcnt) { //fill cells
				document.write(	"<td class=\"tbg5cdc\" title=\""+rcl(i*columni+j)+"\"><span class=\"tbg5era"+rcr(i*columni+j)+
						"\">"+rcc(i*columni+j)+"</span></td>"); //country code
				if (flag == "y") { //show flag
					document.write(	"<td class=\"tbg5cdf\"><img class=\"tbg5cdf\" src=\""+ipath+rcc(i*columni+j)+
							".png\" alt=\""+rcn(i*columni+j)+"\" title=\""+rcn(i*columni+j)+"\"></td>"); }
				document.write(	"<td class=\"tbg5cdn\" title=\""+rce(i*columni+j)+
						"\"><span class=\"tbg5era"+rcr(i*columni+j)+"\">"+rcn(i*columni+j)+"</span></td>"); }} //country name
		document.write("</tr>\r\n"); }
	document.write("</table>\r\n");
}

// some convenience for additional explanations
function doexplain(llngg) {
	document.write(xpltxt[llngg-1]);
}

// test
function checkiban2(iban) {
	ibano = iban.substr(0,2)+(99-checkibancore(iban))+iban.substr(4,iban.length-4);
	return ibano;
}


// english ++++++++++++++++++++++++++++++++++++++++
// country names
ctynm = new Array (	"Andorra","Austria","Bosnia and Herzegovina","Belgium","Bulgaria","Switzerland","Serbia and Montenegro",
					"Cyprus","Czech Republic","Germany","Denmark","Estonia","Spain","Finland",
					"Faroe Islands","France","Great Britain","Gibraltar","Greenland","Greece","Croatia",
					"Hungary","Ireland","Iceland","Italy","Liechtenstein","Lithuania","Luxemburg","Latvia",
					"Monaco","Macedonia","Malta","Mauritius","Netherlands","Norway","Poland","Portugal","Romania",
					"Sweden","Slovenia","Slovak Republic","San Marino","Tunisia","Turkey");
// error messages
altxt = new Array (
	"The IBAN contains illegal characters.",
	"The structure of IBAN is wrong.",
	"The check digits of IBAN are wrong.",
	"Can not check correct length of IBAN because ",
	" is currently not respected.",
	"The length of IBAN is wrong. The IBAN of ",
	" needs to be ",
	" characters long.",
	"The IBAN seems to be correct.",
	"The IBAN is incorrect."
);
// additional explanations
xpltxt = new Array (	"IE Ireland may be used for GB Great Britain accounts in case the servicing bank is situated "+
					"in North Ireland and uses the clearing system of the Republic of Ireland; GG Guernsey and JE Jersey "+
					"are using either GB Great Britain or FR France depending on the clearing system used by the "+
					"servicing bank; GF French Guiana, GP Guadeloupe, MQ Martinique and RE Réunion are using FR France "+
					"and EU REGULATION 2560/2001 applies; NC New Caledonia, PF French Polynesia, PM Saint Pierre and "+
					"Miquelon, TF French Southern Territories, WF Wallis and Futuna and YT Mayotte are using FR France; "+
					"ES Spain includes Canary Islands, Ceuta and Melilla; "+
					"PT Portugal includes Azores and Madeira");
// web page
wptxt = new Array (	0,"Currently the additional length check of following countries is respected (ordered by country code):",
					"last update: ","applies","applies not ","Test of a given IBAN.","Print form",
					"Electronic form","Length: ","Example: ");
// russian ++++++++++++++++++++++++++++++++++++++++
// country names
ctynm = ctynm.concat (new Array ("Андорра","Австрия","Босния и Герцоговина","Бельгия","Болгария","Швейцария","Сербия и Черногория", "Кипр", "Чешская республика", "Германия", "Дания", "Эстония", "Испания", "Финляндия", "Фарерские острова", "Франция", "Великобритания", "Гибралтар", "Остров Гренландия", "Греция", "Хорватия", "Венгрия", "Ирландия", "Исландия", "Италия", "Лихтенштейн", "Литва", "Люксембург", "Латвия", "Монако", "Македония", "Мальта", "Маврикий", "Нидерланды", "Норвегия", "Польша", "Португалия", "Румыния", "Швеция", "Словения", "Словацкая Республика", "Сан-Марино", "Тунис", "Турция"));
// error messages
altxt = altxt.concat (new Array (
	"The IBAN содержит некорректные символы",
	"Структура IBAN неправильна.",
	"Контрольные числа IBAN неправильны.",
	"Невозможно проверить правильную длину IBAN, так как ",
	" на данный момент не соблюдается.",
	"Длина IBAN неправильна. IBAN зоны ",
	" должен состоять из ",
	" символов.",
	" IBAN соответствует стандарту.",
	" IBAN введен неверно."
));
// additional explanations
xpltxt = xpltxt.concat (new Array ("IE (Ирландия) может использоваться для счетов GB (Великобритании) в случае, если обслуживающий банк расположен в Северной Ирландии и использует клиринговую систему Ирландской республики; GG (Гернси) и JE (Джерси) применяют GB (Великобритания) или FR (Франция) в зависимости от системы клиринга, используемой обслуживающим банком; GF (Французская Гвиана), GP (Остров Гваделупа), MQ (Мартиника) и RE (Реюньон)  используются в FR (Франция) и  в Нормативах ЕС 2560/2001; NC (Новая Каледония), PF (Французская Полинезия), PM (Сен-Пьер и Микелон), TF (Французские Южные Территории), WF (Острова Уоллис и Футуна) и YT (Майотте) используют FR (Франция); ES (Испания) включает в себя Канарские Острова, Сеуту и Мелилью; PT (Португалия) включает в себя Азорские острова и Мадейру"));
// web page
wptxt = wptxt.concat (new Array (	0,"На данный момент дополнительная проверка длины следующих стран соблюдена (рассчитана согласно коду страны):", "последняя версия: "," приемлем","неприемлем ","Проверка заданного IBAN.","Форма распечатки", "Электронная форма","Длина: ","Пример: "));
// latvian ++++++++++++++++++++++++++++++++++++++++
// country names
ctynm = ctynm.concat (new Array ("Аndorā","Аustrijā","Bosnijā un Hercegovinā","Beļģijā","Bulgārijā","Šveicē","Serbijā un Melnkalnē","Kiprā","Čehijas Republikā","Vācijā","Dānijā","Igaunijā","Spānijā","Somijā","Farēru salās","Francijā","Lielbritānijā","Gibraltārā","Grenlandē","Grieķijā","Horvātijā","Ungārijā","Īrijā","Islandē","Itālijā","Lihtenšteinā","Lietuvā","Luksemburgā","Latvijā","Monako","Maķedonijā","Maltā","Maurīcijā","Nīderlandē","Norvēģijā","Polijā","Portugālē","Rumānijā","Zviedrijā","Slovēnijā","Slovākijas Republikā","Sanmarīno","Tunisijā","Turcijā"));
// error messages
altxt = altxt.concat (new Array (
	"IBAN satur nekorektus simbolus",
	"IBAN struktūra ir nepareiza.",
	"IBAN kontrolcipari ir nepareizi.",
	"IBAN patieso garumu nav iespējams pārbaudīt, jo par ",
	" nav informācijas.",
	"IBAN garums nepareizs. IBAN ",
	" sastāv no ",
	" simbola/iem.",
	" IBAN atbilst standartam.",
	" IBAN ievadīts nepareizi."
));
// additional explanations
xpltxt = xpltxt.concat (new Array ("IE (Īrija) var tikt izmantots GB (Lielbritānija) kontiem gadījumos, kad apkalpojošā banka atrodas Ziemeļīrijā un izmanto Īrijas republikas klīringa sistēmu; GG (Gērnsija) un JE (Džersija) izmanto GB (Lielbritānija) vai FR (Francija), atkarībā no apkalpojošās bankas klīringa sistēmas; GF (Gviāna), GP (Gvadelupas sala), MQ (Martinika) un RE (Reinjona) izmanto FR (Francija) un Normatīvos ЕС 2560/2001; NC (Jaunkaledonija), PF (Franču Polinēzija), PM (Senpjēra un Mikelona); TF (Francijas Dienvidu teritorijas), WF (Volisa salas un Futuna) un YT (Majota sala) izmanto FR (Francija); ES (Spānija) iekļautas Kanāriju salas, Seūta un Melilja; PT (Portugāle) iekļautas Azoru salas un Madeira."));
// web page
wptxt = wptxt.concat (new Array (	0,"Šobrīd papildus simbolu skaita pārbaude tiek veikta sekojošām valstīm (aprēķināta atbilstoši valsts kodam):", "pēdējā versija: ", "atbilst", "neatbilst", "ievadītā IBAN pārbaude.", "Izdrukas forma", "Elektroniskā forma", "Garums: " , "Piemērs: "));
