/*
 * tasukeCompAccArray.js
 * http://tasuke.dna.affrc.go.jp/
 *
 * Author: Jungsok Kim, Ryutaro Itoh, Norio Tabei
 *
 * Copyright (c) 2025 National Institute of Agrobiological Sciences
 *
 * Required Modules:
 * lib/lz-string/lz-string.min.js
*/
var tasukeCompAccArray = function() { }

// Static methods
tasukeCompAccArray.uint8arrayToBinstr = function(bin8) {
	var bstr = "";
	for(var i=0,len=bin8.length; i<len; i++) {
		bstr += String.fromCharCode(bin8[i]);
	}
	return bstr;
}
tasukeCompAccArray.binstrToUint8array = function(bstr) {
	return Uint8Array.from(Array.prototype.map.call(bstr, function(x) {
		return x.charCodeAt(0);
	}));
}

tasukeCompAccArray.base64ToUrlsafe = function(b64) {
	return b64.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
}
tasukeCompAccArray.urlsafeToBase64 = function(urlSafe) {
	return urlSafe.replace(/-/g, "+").replace(/_/g, "/");
}


tasukeCompAccArray.encodeUrlSafe = function(dbArr, opt={}) {
	var dbNumArr = [];
	for(var i=0,len=dbArr.length; i<len; i++) {
		var num = /^d(\d+)$/.exec(dbArr[i])[1];
		if(num === null) throw new Error("Invalid accession_db: " + dbArr[i]);
		dbNumArr.push(num);
	}
	var bin16 = new Uint16Array(dbNumArr);
	var bin8 = new Uint8Array(bin16.buffer);
	
	var bstr = this.uint8arrayToBinstr(bin8);
	var b64 = "";
	if("compress" in opt && opt["compress"]) {
		b64 = LZString.compressToEncodedURIComponent(bstr);
//		b64 = LZString.compressToBase64(bstr);
//		b64 = this.base64ToUrlsafe(b64);
	} else {
		b64 = btoa(bstr);
		b64 = this.base64ToUrlsafe(b64);
	}
//console.log(bstr + " (" + bstr.length + ")");
//console.log(b64 + " (" + b64.length + ")");
	return b64;
}
tasukeCompAccArray.decodeUrlSafe = function(b64, opt={}) {
	var bstr = "";
	if("compress" in opt && opt["compress"]) {
		bstr = LZString.decompressFromEncodedURIComponent(b64);
	} else {
		b64 = this.urlsafeToBase64(b64);
		bstr = atob(b64);
	}
	var bin8 = this.binstrToUint8array(bstr);
	var bin16 = new Uint16Array(bin8.buffer);
	var dbNumArr = Array.from(bin16);
	var dbArr = [];
	for(var i=0,len=dbNumArr.length; i<len; i++) {
		dbArr.push("d" + dbNumArr[i]);
	}
	return dbArr;
}

function sendCompAccDbWithAjax(targetAccIdArr, callback) {
	if(!targetAccIdArr ||  !(targetAccIdArr instanceof Array) || !callback) return;

	 $.ajax({
		"url": "./bin/list.php",
		"cache": false,
		"type": "POST",
		"async": "true",
		"data": {"prm_ext_acc": ""}
	}).done(function(data){
		var a=data.split("|");
		var accObjArray = JSON.parse(a[0]);

		var id2db = {};
		for(var i=0,len=accObjArray.length; i<len; i++) {
			id2db[accObjArray[i]["id"]] = accObjArray[i]["db"];
		}

		var dbs = [];
		for(var i=0,len=targetAccIdArr.length; i<len; i++) {
			 if(targetAccIdArr[i] in id2db) dbs.push(id2db[targetAccIdArr[i]]);
		}
		var cdbStr = tasukeCompAccArray.encodeUrlSafe(dbs, {compress:true});
		callback(cdbStr);
	}).fail(function(jqXHR, textStatus, errorThrown) {
		console.error(jqXHR);
	});
}
function receiveCompAccDbWithAjax(cdbStr, callback) {
	$.ajax({
		"url": "./bin/list.php",
		"cache": false,
		"type": "POST",
		"async": "true",
		"data": {"prm_ext_acc": ""}
	}).done(function(data){
		var a=data.split("|");
		var accObjArray = JSON.parse(a[0]);

		var db2id = {};
		for(var i=0,len=accObjArray.length; i<len; i++) {
			db2id[accObjArray[i]["db"]] = accObjArray[i]["id"];
		}
		var dbsArr = tasukeCompAccArray.decodeUrlSafe(cdbStr, {compress:true});
		var ids = [];
		for(var i=0,len=dbsArr.length; i<len; i++) {
			if(dbsArr[i] in db2id) ids.push(db2id[dbsArr[i]]);
		}
		callback(ids);
	}).fail(function(jqXHR, textStatus, errorThrown) {
		console.error(jqXHR);
	});
}
