/*
******************************************************************************
*   Copyright (C) 1997-2001, International Business Machines
*   Corporation and others.  All Rights Reserved.
******************************************************************************
*   file name:  nfsubs.h
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
* Modification history
* Date        Name      Comments
* 10/11/2001  Doug      Ported from ICU4J
*/

#ifndef NFSUBS_H
#define NFSUBS_H

#include "unicode/utypes.h"
#include "unicode/decimfmt.h"
#include "nfrs.h"
#include "nfrule.h"
#include "llong.h"
#include <float.h>

U_NAMESPACE_BEGIN

class NFSubstitution {
    int32_t pos;
    const NFRuleSet* ruleSet;
    const DecimalFormat* numberFormat;
    
protected:
    NFSubstitution(int32_t pos,
        const NFRuleSet* ruleSet,
        const RuleBasedNumberFormat* rbnf,
        const UnicodeString& description,
        UErrorCode& status);
    
    const NFRuleSet* getRuleSet() const { return ruleSet; }
    const DecimalFormat* getNumberFormat() const { return numberFormat; }
    
public:
    static NFSubstitution* makeSubstitution(int32_t pos, 
        const NFRule* rule, 
        const NFRule* predecessor,
        const NFRuleSet* ruleSet, 
        const RuleBasedNumberFormat* rbnf, 
        const UnicodeString& description,
        UErrorCode& status);
    
    virtual ~NFSubstitution();
    
    virtual UBool operator==(const NFSubstitution& rhs) const;
    UBool operator!=(const NFSubstitution& rhs) const { return !operator==(rhs); }
    
    /**
     * Sets the substitution's divisor.  Used by NFRule.setBaseValue().
     * A no-op for all substitutions except multiplier and modulus
     * substitutions.
     * @param radix The radix of the divisor
     * @param exponent The exponent of the divisor
     */
    virtual void setDivisor(int32_t radix, int32_t exponent);
    
    /**
     * Replaces result with the string describing the substitution.
     */
    virtual void toString(UnicodeString& result) const;
    
    //-----------------------------------------------------------------------
    // formatting
    //-----------------------------------------------------------------------
    
    /**
     * Performs a mathematical operation on the number, formats it using
     * either ruleSet or decimalFormat, and inserts the result into
     * toInsertInto.
     * @param number The number being formatted.
     * @param toInsertInto The string we insert the result into
     * @param pos The position in toInsertInto where the owning rule's
     * rule text begins (this value is added to this substitution's
     * position to determine exactly where to insert the new text)
     */
    virtual void doSubstitution(const llong &number, UnicodeString& toInsertInto, int32_t pos) const;
    virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos) const;
    
protected:
    /**
     * Subclasses override this function to perform some kind of
     * mathematical operation on the number.  The result of this operation
     * is formatted using the rule set or DecimalFormat that this
     * substitution refers to, and the result is inserted into the result
     * string.
     * @param The number being formatted
     * @return The result of performing the opreration on the number
     */
    virtual llong  transformNumber(const llong &number) const = 0;
    virtual double transformNumber(double number) const = 0;
    
public:
    //-----------------------------------------------------------------------
    // parsing
    //-----------------------------------------------------------------------
    
    /**
     * Parses a string using the rule set or DecimalFormat belonging
     * to this substitution.  If there's a match, a mathematical
     * operation (the inverse of the one used in formatting) is
     * performed on the result of the parse and the value passed in
     * and returned as the result.  The parse position is updated to
     * point to the first unmatched character in the string.
     * @param text The string to parse
     * @param parsePosition On entry, ignored, but assumed to be 0.
     * On exit, this is updated to point to the first unmatched
     * character (or 0 if the substitution didn't match)
     * @param baseValue A partial parse result that should be
     * combined with the result of this parse
     * @param upperBound When searching the rule set for a rule
     * matching the string passed in, only rules with base values
     * lower than this are considered
     * @param lenientParse If true and matching against rules fails,
     * the substitution will also try matching the text against
     * numerals using a default-costructed NumberFormat.  If false,
     * no extra work is done.  (This value is false whenever the
     * formatter isn't in lenient-parse mode, but is also false
     * under some conditions even when the formatter _is_ in
     * lenient-parse mode.)
     * @return If there's a match, this is the result of composing
     * baseValue with whatever was returned from matching the
     * characters.  This will be either a Long or a Double.  If there's
     * no match this is new Long(0) (not null), and parsePosition
     * is left unchanged.
     */
    virtual UBool doParse(const UnicodeString& text, 
        ParsePosition& parsePosition, 
        double baseValue,
        double upperBound, 
        UBool lenientParse,
        Formattable& result) const;
    
    /**
     * Derives a new value from the two values passed in.  The two values
     * are typically either the base values of two rules (the one containing
     * the substitution and the one matching the substitution) or partial
     * parse results derived in some other way.  The operation is generally
     * the inverse of the operation performed by transformNumber().
     * @param newRuleValue The value produced by matching this substitution
     * @param oldRuleValue The value that was passed to the substitution
     * by the rule that owns it
     * @return A third value derived from the other two, representing a
     * partial parse result
     */
    virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const = 0;
    
    /**
     * Calculates an upper bound when searching for a rule that matches
     * this substitution.  Rules with base values greater than or equal
     * to upperBound are not considered.
     * @param oldUpperBound The current upper-bound setting.  The new
     * upper bound can't be any higher.
     */
    virtual double calcUpperBound(double oldUpperBound) const = 0;
    
    //-----------------------------------------------------------------------
    // simple accessors
    //-----------------------------------------------------------------------
    
    /**
     * Returns the substitution's position in the rule that owns it.
     * @return The substitution's position in the rule that owns it.
     */
    int32_t getPos() const { return pos; }
    
    /**
     * Returns the character used in the textual representation of
     * substitutions of this type.  Used by toString().
     * @return This substitution's token character.
     */
    virtual UChar tokenChar() const = 0;
    
    /**
     * Returns true if this is a null substitution.  (We didn't do this
     * with instanceof partially because it causes source files to
     * proliferate and partially because we have to port this to C++.)
     * @return true if this object is an instance of NullSubstitution
     */
    virtual UBool isNullSubstitution() const;
    
    /**
     * Returns true if this is a modulus substitution.  (We didn't do this
     * with instanceof partially because it causes source files to
     * proliferate and partially because we have to port this to C++.)
     * @return true if this object is an instance of ModulusSubstitution
     */
    virtual UBool isModulusSubstitution() const;
    
private:
    static const char fgClassID;
    
public:
    static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
    virtual UClassID getDynamicClassID(void) const;
};

class SameValueSubstitution : public NFSubstitution {
public:
    SameValueSubstitution(int32_t pos,
        const NFRuleSet* ruleset,
        const RuleBasedNumberFormat* formatter,
        const UnicodeString& description,
        UErrorCode& status);
    
    llong transformNumber(const llong &number) const { return number; }
    double transformNumber(double number) const { return number; }
    double composeRuleValue(double newRuleValue, double /*oldRuleValue*/) const { return newRuleValue; }
    double calcUpperBound(double oldUpperBound) const { return oldUpperBound; }
    UChar tokenChar() const { return (UChar)0x003d; } // '='
private:
    static const char fgClassID;
    
public:
    static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
    virtual UClassID getDynamicClassID(void) const;
};

class MultiplierSubstitution : public NFSubstitution {
    double divisor;
    llong ldivisor;
    
public:
    MultiplierSubstitution(int32_t _pos,
        double _divisor,
        const NFRuleSet* _ruleSet,
        const RuleBasedNumberFormat* formatter,
        const UnicodeString& description,
        UErrorCode& status)
        : NFSubstitution(_pos, _ruleSet, formatter, description, status), divisor(_divisor)
    {
        ldivisor = _divisor;
    }
    
    void setDivisor(int32_t radix, int32_t exponent) { 
        divisor = uprv_pow(radix, exponent);
        ldivisor = divisor;
    }
    
    UBool operator==(const NFSubstitution& rhs) const;
    
    llong transformNumber(const llong &number) const {
        return number / ldivisor;
    }
    
    double transformNumber(double number) const {
        return uprv_floor(number / divisor);
    }
    
    double composeRuleValue(double newRuleValue, double /*oldRuleValue*/) const {
        return newRuleValue * divisor;
    }
    
    double calcUpperBound(double /*oldUpperBound*/) const { return divisor; }
    
    UChar tokenChar() const { return (UChar)0x003c; } // '<'
private:
    static const char fgClassID;
    
public:
    static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
    virtual UClassID getDynamicClassID(void) const;
};

class ModulusSubstitution : public NFSubstitution {
    double divisor;
    llong  ldivisor;
    const NFRule* ruleToUse;
public:
    ModulusSubstitution(int32_t pos,
        double _divisor,
        const NFRule* rulePredecessor,
        const NFRuleSet* ruleSet,
        const RuleBasedNumberFormat* formatter,
        const UnicodeString& description,
        UErrorCode& status);
    
    void setDivisor(int32_t radix, int32_t exponent) { 
        divisor = uprv_pow(radix, exponent);
        ldivisor = divisor;
    }
    
    UBool operator==(const NFSubstitution& rhs) const;
    
    void doSubstitution(const llong &number, UnicodeString& toInsertInto, int32_t pos) const;
    void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos) const;
    
    llong transformNumber(const llong &number) const { return number % ldivisor; }
    double transformNumber(double number) const { return uprv_fmod(number, divisor); }
    
    UBool doParse(const UnicodeString& text, 
        ParsePosition& parsePosition,
        double baseValue,
        double upperBound,
        UBool lenientParse,
        Formattable& result) const;
    
    double composeRuleValue(double newRuleValue, double oldRuleValue) const {
        return oldRuleValue - uprv_fmod(oldRuleValue, divisor) + newRuleValue;
    }
    
    double calcUpperBound(double /*oldUpperBound*/) const { return divisor; }
    
    UBool isModulusSubstitution() const { return TRUE; }
    
    UChar tokenChar() const { return (UChar)0x003e; } // '>'
private:
    static const char fgClassID;
    
public:
    static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
    virtual UClassID getDynamicClassID(void) const;
};

class IntegralPartSubstitution : public NFSubstitution {
public:
    IntegralPartSubstitution(int32_t _pos,
        const NFRuleSet* _ruleSet,
        const RuleBasedNumberFormat* formatter,
        const UnicodeString& description,
        UErrorCode& status)
        : NFSubstitution(_pos, _ruleSet, formatter, description, status) {}
    
    llong transformNumber(const llong &number) const { return number; }
    double transformNumber(double number) const { return uprv_floor(number); }
    double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue + oldRuleValue; }
    double calcUpperBound(double /*oldUpperBound*/) const { return DBL_MAX; }
    UChar tokenChar() const { return (UChar)0x003c; } // '<'
private:
    static const char fgClassID;
    
public:
    static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
    virtual UClassID getDynamicClassID(void) const;
};

class FractionalPartSubstitution : public NFSubstitution {
    UBool byDigits;
    UBool useSpaces;
    enum { kMaxDecimalDigits = 8 };
public:
    FractionalPartSubstitution(int32_t pos,
        const NFRuleSet* ruleSet,
        const RuleBasedNumberFormat* formatter,
        const UnicodeString& description,
        UErrorCode& status);
    
    UBool operator==(const NFSubstitution& rhs) const;
    
    void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos) const;
    void doSubstitution(const llong &/*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/) const {}
    llong transformNumber(const llong &/*number*/) const { return llong(0,0); }
    double transformNumber(double number) const { return number - uprv_floor(number); }
    
    UBool doParse(const UnicodeString& text,
        ParsePosition& parsePosition,
        double baseValue,
        double upperBound,
        UBool lenientParse,
        Formattable& result) const;
    
    double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue + oldRuleValue; }
    double calcUpperBound(double /*oldUpperBound*/) const { return 0.0; }
    UChar tokenChar() const { return (UChar)0x003e; } // '>'
private:
    static const char fgClassID;
    
public:
    static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
    virtual UClassID getDynamicClassID(void) const;
};

class AbsoluteValueSubstitution : public NFSubstitution {
public:
    AbsoluteValueSubstitution(int32_t _pos,
        const NFRuleSet* _ruleSet,
        const RuleBasedNumberFormat* formatter,
        const UnicodeString& description,
        UErrorCode& status)
        : NFSubstitution(_pos, _ruleSet, formatter, description, status) {}
    
    llong transformNumber(const llong &number) const { return number.abs(); }
    double transformNumber(double number) const { return uprv_fabs(number); }
    double composeRuleValue(double newRuleValue, double /*oldRuleValue*/) const { return -newRuleValue; }
    double calcUpperBound(double /*oldUpperBound*/) const { return DBL_MAX; }
    UChar tokenChar() const { return (UChar)0x003e; } // '>'
private:
    static const char fgClassID;
    
public:
    static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
    virtual UClassID getDynamicClassID(void) const;
};

class NumeratorSubstitution : public NFSubstitution {
    double denominator;
    llong ldenominator;
public:
    NumeratorSubstitution(int32_t _pos,
        double _denominator,
        const NFRuleSet* _ruleSet,
        const RuleBasedNumberFormat* formatter,
        const UnicodeString& description,
        UErrorCode& status)
        : NFSubstitution(_pos, _ruleSet, formatter, description, status), denominator(_denominator) 
    {
        ldenominator = _denominator;
    }
    
    UBool operator==(const NFSubstitution& rhs) const;
    
    llong transformNumber(const llong &number) const { return number * ldenominator; }
    double transformNumber(double number) const { return uprv_round(number * denominator); }
    
    UBool doParse(const UnicodeString& text, 
        ParsePosition& parsePosition,
        double baseValue,
        double upperBound,
        UBool /*lenientParse*/,
        Formattable& result) const 
    {
        // we don't have to do anything special to do the parsing here,
        // but we have to turn lenient parsing off-- if we leave it on,
        // it SERIOUSLY messes up the algorithm
        return NFSubstitution::doParse(text, parsePosition, baseValue, upperBound, FALSE, result);
    }
    double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue / oldRuleValue; }
    double calcUpperBound(double /*oldUpperBound*/) const { return denominator; }
    UChar tokenChar() const { return (UChar)0x003c; } // '<'
private:
    static const char fgClassID;
    
public:
    static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
    virtual UClassID getDynamicClassID(void) const;
};

class NullSubstitution : public NFSubstitution {
public:
    NullSubstitution(int32_t _pos,
        const NFRuleSet* _ruleSet,
        const RuleBasedNumberFormat* formatter,
        const UnicodeString& description,
        UErrorCode& status)
        : NFSubstitution(_pos, _ruleSet, formatter, description, status) {}
    
    void toString(UnicodeString& /*result*/) const {}
    void doSubstitution(double /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/) const {}
    void doSubstitution(const llong &/*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/) const {}
    llong transformNumber(const llong &/*number*/) const { return llong(0,0); }
    double transformNumber(double /*number*/) const { return 0; }
    UBool doParse(const UnicodeString& /*text*/,
                ParsePosition& /*parsePosition*/, 
                double baseValue,
                double /*upperBound*/,
                UBool /*lenientParse*/,
                Formattable& result) const
            { result.setDouble(baseValue); return TRUE; }
    double composeRuleValue(double /*newRuleValue*/, double /*oldRuleValue*/) const { return 0.0; } // never called
    double calcUpperBound(double /*oldUpperBound*/) const { return 0; } // never called
    UBool isNullSubstitution() const { return TRUE; }
    UChar tokenChar() const { return (UChar)0x0020; } // ' ' never called
private:
    static const char fgClassID;
    
public:
    static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
    virtual UClassID getDynamicClassID(void) const;
};

U_NAMESPACE_END

// NFSUBS_H
#endif
