/*
******************************************************************************
*   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 "nfrule.h"
#if U_HAVE_RBNF

#include "unicode/utypes.h"
#include "unicode/decimfmt.h"
#include "nfrs.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(int64_t 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 int64_t transformNumber(int64_t 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);
    
    int64_t transformNumber(int64_t 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;
    int64_t 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 = util64_fromDouble(divisor);
    }
    
    void setDivisor(int32_t radix, int32_t exponent) { 
        divisor = uprv_pow(radix, exponent);
        ldivisor = util64_fromDouble(divisor);
    }
    
    UBool operator==(const NFSubstitution& rhs) const;
    
    int64_t transformNumber(int64_t 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;
    int64_t  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 = util64_fromDouble(divisor);
    }
    
    UBool operator==(const NFSubstitution& rhs) const;
    
    void doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t pos) const;
    void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos) const;
    
    int64_t transformNumber(int64_t 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) {}
    
    int64_t transformNumber(int64_t 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(int64_t /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/) const {}
    int64_t transformNumber(int64_t /*number*/) const { return 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) {}
    
    int64_t transformNumber(int64_t number) const { return number >= 0 ? number : -number; }
    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;
    int64_t 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 = util64_fromDouble(denominator);
    }
    
    UBool operator==(const NFSubstitution& rhs) const;
    
    int64_t transformNumber(int64_t 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(int64_t /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/) const {}
    int64_t transformNumber(int64_t /*number*/) const { return 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

/* U_HAVE_RBNF */
#endif

// NFSUBS_H
#endif
