package lc.mecha.math;

import org.apache.commons.lang.StringUtils;

/**
 * Encode and decode strings using an arbitrary radix and a user-supplied code alphabet.
 *
 * @author Alex Leigh
 */
public class RadixConverter {
    public static final String RADIX36 = "0123456789abcdefghijklmnopqrstuvwxyz";
    private final String code;

    /**
     * Create a new radix converter with the given code. For example,
     * <code>0123456789abcdefghijklmnopqrstuvwxyz</code>.
     *
     * @param code The code to use.
     */

    public RadixConverter(String code) {
        this.code = code;
    }

    /**
     * Encode the given number into the arbitrary radix code specified by this class.
     */
    public String encode(int num) {
        int j = (int) Math.ceil(Math.log(num) / Math.log(code.length()));
        StringBuffer text = new StringBuffer();
        for (int i = 0; i < j; i++) {
            //i goes to log base code.length() of num (using change of base formula)
            text.append(code.charAt(num % code.length()));
            num /= code.length();
        }
        return StringUtils.reverse(text.toString());
    }

    /**
     * Decide the given number in strong format to an integer, using the arbitrary radix code specified by this
     * class.
     */
    public int decode(String text) {
        int num = 0;
        int j = text.length();
        for (int i = 0; i < j; i++) {
            num += code.indexOf(text.charAt(0)) * Math.pow(code.length(), i);
            text = text.substring(1);
        }
        return num;
    }
}
