package uk.me.nxg.unity;

class UnitWriterCds extends UnitWriter {

    public UnitWriterCds(UnitExpr ue) {
        super(ue);
    }

    public String write() {
        StringBuilder sb = new StringBuilder();
        boolean first = true;

        try {
            double lf = ue.getLogFactor();
            if (lf == 0.0) {
                // do nothing
            } else if (Math.abs(lf) <= 2.0) {
                writeNumber(sb, Math.pow(10, lf));
            } else {
                double low = Math.floor(lf);
                double logmantissa = lf - low;
                if (logmantissa == 0.0) {
                    // round number
                    sb.append("10");
                    if (lf > 0.0) {
                        sb.append('+');
                    }
                    writeNumber(sb, lf);
                } else {
                    writeNumber(sb, Math.pow(10, logmantissa));
                    sb.append("x10");
                    if (low > 0) {
                        sb.append("+");
                    }
                    writeNumber(sb, low);
                }
            }
            for (OneUnit u : ue) {
                double e = u.getExponent();
                if (e == 1.0) {
                    if (!first) {
                        sb.append('.');
                    }
                    sb.append(u.unitString(Syntax.CDS));
                } else if (e < 0.0) {
                    sb.append('/').append(u.unitString(Syntax.CDS));
                    if (e != -1.0) {
                        writeNumber(sb, -e);
                    }
                } else {
                    // e is positive and not 1.0
                    if (!first) {
                        sb.append('.');
                    }
                    sb.append(u.unitString(Syntax.CDS));
                    writeNumber(sb, e);
                }
                first = false;
            }
            return sb.toString();
        } catch (UnitParserException e) {
            throw new AssertionError("units system failed to recognise built-in syntax CDS: " + e);
        }
    }

    void writeNumber(StringBuilder sb, double d) {
        writeNumber(sb, d, false, false, false, false);
    }
}
