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;

    /**
     * Constructs the converter by preparing its reference for translating roman
     * character into numeric values.
     */
    public RomanConverter() {
        this.charValues = RomanCharMapFactory.generateCharPairsArray();
    }

    /**
     * Converts the given syntactically correct roman numeral as String to its
     * int value.
     *
     * This method performs no checks on the correctness of the roman numeral
     * String so the correct result is <b>not</b> guaranteed if the input is
     * incorrect.
     *
     * Works with 2 indexes: one is iterating through the given romanString, the
     * other through the reference array of Pairs
     * {@link RomanCharMapFactory#generateCharPairsArray() (roman char, value)}.
     * The array is iterated until a char the romanString starts with is found:
     * its values is added to the arabicValue and the search continues on the
     * next romanString char (or pair of chars).
     *
     * @param romanString a string representing a syntactically correct roman
     * numeral to be converted.
     * @return int value of the given String.
     */
    public int romanStringToInteger(String romanString) {
        int arabicValue = 0;
        int romanStringIndex = 0;
        int romanCharIndex = 0;
        while (romanStringIndex < romanString.length()) {
            String romanChar = (String) charValues[romanCharIndex].getKey();
            int romanCharValue = (int) charValues[romanCharIndex].getValue();
            if (romanString.startsWith(romanChar, romanStringIndex)) {
                arabicValue += romanCharValue;
                romanStringIndex += romanChar.length();
            } else {
                romanCharIndex++;
            }
        }
        return arabicValue;
    }
    
    /**
     * 
     * 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).
            int romanCharValue = (int) charAndValue.getValue();
            String romanChar = (String) charAndValue.getKey();
            while (arabic >= romanCharValue) {
                romanString += romanChar;
                arabic -= romanCharValue;
            }
        }
        //RomanNumeral roman = new RomanNumeral(romanString);
        return romanString;
    }
}

@@ -109,19 +109,45 @@
 als 
-to arabic i
+as Strings to arabic numerals%0A * as I
 nteg
@@ -153,19 +153,16 @@
 gers and
-%0A *
  vice-ve
@@ -164,24 +164,28 @@
 ce-versa.%0A *
+ %3Cp%3E
 %0A * Uses Rom
@@ -181,16 +181,25 @@
  * Uses 
+a %7B@link 
 RomanCha
@@ -209,16 +209,17 @@
 pFactory
+%7D
  generat
@@ -225,18 +225,56 @@
 ted 
-structures
+array of pairs (romanChar, its%0A * integer value)
  as 
@@ -299,19 +299,16 @@
 slations
-%0A *
  of the 
@@ -329,16 +329,19 @@
  numeral
+%0A *
  systems
@@ -880,32 +880,36 @@
 nt value.%0A     *
+ %3Cp%3E
 %0A     * This met
@@ -1064,32 +1064,36 @@
 ncorrect.%0A     *
+ %3Cp%3E
 %0A     * Works wi
@@ -2320,21 +2320,17 @@
 ;%0A    %7D%0A
-    
 %0A
+
     /**%0A
@@ -2340,170 +2340,990 @@
   * 
-%0A     * Based on            %0A     * http://www.fredosaurus.com/notes-java/examples/components/romanNumerals/romanNumeral.html%0A     * @param arabic%0A     * @return 
+Converts the given int value to its representation in roman numerals as%0A     * String.%0A     * %3Cp%3E%0A     * Throws an exception if the given int is not positve or is bigger than%0A     * 3999, which are the extremes of the roman numerals range of%0A     * representation.%0A     * %3Cp%3E%0A     * The algorithm is based on the%0A     * %3Ca href=%22http://www.fredosaurus.com/notes-java/examples/components/romanNumerals/romanNumeral.html%22%3Efredosaurus.com%3C/a%3E%0A     * roman numerals example. Iterates through the array of roman chars and%0A     * appends as many chars as necessary to the output string so that the value%0A     * could not be decreased anymore with the same roman char. Then switches to%0A     * a char with less value.%0A     *%0A     * @param arabic int to be converted to a roman numeral as String.%0A     * @return a string representing a sytactically correct roman numeral with%0A     * the given value.%0A     * @throws IllegalArgumentException if the arabic int is not in %5B1, 3999%5D%0A     * range.
 %0A   

Improve class JavaDoc and add integerToRomanString() JavaDoc