// Encoding documentation:
// https://en.wikipedia.org/wiki/Code_39#Encoding

import Barcode from "../Barcode.js";

class CODE39 extends Barcode {
	constructor(data, options){
		data = data.toUpperCase();

		// Calculate mod43 checksum if enabled
		if(options.mod43){
			data += getCharacter(mod43checksum(data));
		}

		super(data, options);
	}

	encode(){
		// First character is always a *
		var result = getEncoding("*");

		// Take every character and add the binary representation to the result
		for(let i = 0; i < this.data.length; i++){
			result += getEncoding(this.data[i]) + "0";
		}

		// Last character is always a *
		result += getEncoding("*");

		return {
			data: result,
			text: this.text
		};
	}

	valid(){
		return this.data.search(/^[0-9A-Z\-\.\ \$\/\+\%]+$/) !== -1;
	}
}






// All characters. The position in the array is the (checksum) value
var characters = [
	"0", "1", "2", "3",
	"4", "5", "6", "7",
	"8", "9", "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",
	"-", ".", " ", "$",
	"/", "+", "%", "*"
];

// The decimal representation of the characters, is converted to the
// corresponding binary with the getEncoding function
var encodings = [
	20957, 29783, 23639, 30485,
	20951, 29813, 23669, 20855,
	29789, 23645, 29975, 23831,
	30533, 22295, 30149, 24005,
	21623, 29981, 23837, 22301,
	30023, 23879, 30545, 22343,
	30161, 24017, 21959, 30065,
	23921, 22385, 29015, 18263,
	29141, 17879, 29045, 18293,
	17783, 29021, 18269, 17477,
	17489, 17681, 20753, 35770
];

// Get the binary representation of a character by converting the encodings
// from decimal to binary
function getEncoding(character){
	return getBinary(characterValue(character));
}

function getBinary(characterValue){
	return encodings[characterValue].toString(2);
}

function getCharacter(characterValue){
	return characters[characterValue];
}

function characterValue(character){
	return characters.indexOf(character);
}

function mod43checksum(data){
	var checksum = 0;
	for(let i = 0; i < data.length; i++){
		checksum += characterValue(data[i]);
	}

	checksum = checksum % 43;
	return checksum;
}

export {CODE39};
