package it.matjaz.numerus.core;

import javafx.util.Pair;

/**
 * Offers conversion methods from roman numerals to arabic integers and
 * vice-versa.
 *
 * Uses RomanCharMapFactory generated structures as reference for translations
 * of the digits in both numeral systems.
 *
 * @author Matjaž <a href="mailto:dev@matjaz.it">dev@matjaz.it</a>
 * <a href="http://matjaz.it">www.matjaz.it</a>
 */
public class RomanConverter {

    private final Pair[] charValues;

    public RomanConverter() {
        this.charValues = RomanCharMapFactory.generateCharPairsArray();
    }

    public Pair[] getCharValues() {
        return charValues;
    }
    
    public int romanStringToInteger(String roman) {
        int arabic = 0;
        int i = 0;
        while (!roman.isEmpty()) {
            Pair romanChar = charValues[i];
            if (roman.startsWith((String) romanChar.getKey())) {
                arabic += (Integer) romanChar.getValue();
                roman = roman.replaceFirst((String) romanChar.getKey(), "");
            } else {
                i++;
            }
        }
        return arabic;
    }
    
    /**
     * 
     * Based on            
     * http://www.fredosaurus.com/notes-java/examples/components/romanNumerals/romanNumeral.html
     * @param arabic
     * @return 
     */
    public String integerToRomanString(int arabic) {
        if (arabic < 1 || arabic > 3999) {
            throw new IllegalArgumentException("Arabic numeral should be an integer in [1, 3999].");
        } 
        String romanString = "";
        for (Pair charAndValue : charValues) {
            // Remove as many of this value as possible (maybe none).
            while (arabic >= (int) charAndValue.getValue()) {
                romanString += (String) charAndValue.getKey();
                arabic -= (int) charAndValue.getValue();
            }
        }
        //RomanNumeral roman = new RomanNumeral(romanString);
        return romanString;
    }
}

@@ -689,16 +689,22 @@
 ng roman
+String
 ) %7B%0A    
@@ -717,16 +717,21 @@
 t arabic
+Value
  = 0;%0A  
@@ -740,17 +740,64 @@
     int 
-i
+romanStringIndex = 0;%0A        int romanCharIndex
  = 0;%0A  
@@ -813,70 +813,204 @@
 le (
-!
 roman
-.isEmpty()) %7B%0A            Pair romanChar = charValues%5Bi%5D
+StringIndex %3C romanString.length()) %7B%0A            String romanChar = (String) charValues%5BromanCharIndex%5D.getKey();%0A            int romanCharValue = (int) charValues%5BromanCharIndex%5D.getValue()
 ;%0A  
@@ -1028,16 +1028,22 @@
 f (roman
+String
 .startsW
@@ -1050,35 +1050,35 @@
 ith(
-(String) romanChar.getKey()
+romanChar, romanStringIndex
 )) %7B
@@ -1104,21 +1104,16 @@
 abic
- += (Integer)
+Value +=
  rom
@@ -1118,27 +1118,21 @@
 omanChar
-.get
 Value
-()
 ;%0A      
@@ -1150,61 +1150,40 @@
 oman
- = roman.replaceFirst((String) romanChar.getKey(), %22%22
+StringIndex += romanChar.length(
 );%0A 
@@ -1218,17 +1218,30 @@
         
-i
+romanCharIndex
 ++;%0A    
@@ -1281,16 +1281,21 @@
 n arabic
+Value
 ;%0A    %7D%0A

Optimize romanStringToInteger()