interface Measurement {
    getText : () => string;
}

/**
 * A measure is ALWAYS created in Centimeters.
 * How a measure gets displayed can get changed later, so always use this class for measures!
 * If you're american, use the helper static functions fromInches, fromFeet to get centimeters.
 * For instance, 5'10" would get created as:
 * new Measure(Measure.fromFeet(5) + Measure.fromInches(10)
 *
 * If multiple measurements are added, it's treated as area of something simple like rectangles or cubes or whatever, they're just multiplied.
 */
class Measure implements Measurement {
    private units : number;
    private sides : number;

    public constructor (...sides : Array<number>) {
        this.units = 1;
        sides.forEach((side) => {
            this.units *= side;
        });
        this.sides = sides.length;
    }

    //                      ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
    private superscript =   ["" , "" , "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"];

    public getText () {
        let meters = Math.pow(this.sides, 100);
        if (this.units > meters) {
            return (+(this.units / meters).toFixed(2)).toString() + "m" + this.superscript[this.sides];
        } else {
            return this.units.toString() + "cm" + this.superscript[this.sides];
        }
    }

    public getNumber () {
        return this.units;
    }

    public getSides () {
        return this.sides;
    }

    public static fromInches (inches : number) {
        return inches * 2.54;
    }

    public static fromFeet (feet : number) {
        return feet * 30.48;
    }
}

class MeasureLiquid implements Measurement {
    private units : number;

    public constructor (milliliters : number) {
        this.units = milliliters;
    }

    public getText () {
        if (this.units > 1000) {
            return (+(this.units / 1000).toFixed(2)).toString() + "L";
        } else {
            return this.units.toString() + "mL";
        }
    }

    public static fromLiters (liters : number) {
        return liters * 1000;
    }
}