// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2008, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.impl.jdkadapter;

import java.text.CollationKey;

import com.ibm.icu.text.Collator;

/**
 * CollatorICU is an adapter class which wraps ICU4J Collator and
 * implements java.text.Collator APIs.
 */
public class CollatorICU extends java.text.Collator {

    private Collator fIcuCollator;

    private CollatorICU(Collator icuCollator) {
        fIcuCollator = icuCollator;
    }

    public static java.text.Collator wrap(Collator icuCollator) {
        return new CollatorICU(icuCollator);
    }

    public Collator unwrap() {
        return fIcuCollator;
    }

    @Override
    public Object clone() {
        CollatorICU other = (CollatorICU)super.clone();
        try {
            other.fIcuCollator = (Collator)fIcuCollator.clone();
        } catch (CloneNotSupportedException e) {
            // ICU Collator clone() may throw CloneNotSupportedException,
            // but JDK does not.  We use UnsupportedOperationException instead
            // as workwround.
            throw new UnsupportedOperationException("clone() is not supported by this ICU Collator.");
        }
        return other;
    }

    @Override
    public int compare(Object o1, Object o2) {
        return fIcuCollator.compare(o1, o2);
    }

    @Override
    public int compare(String source, String target) {
        return fIcuCollator.compare(source, target);
    }

    @Override
    public boolean equals(Object that) {
        if (that instanceof CollatorICU) {
            return ((CollatorICU)that).fIcuCollator.equals(fIcuCollator);
        }
        return false;
    }

    @Override
    public boolean equals(String source, String target) {
        return fIcuCollator.equals(source, target);
    }

    @Override
    public CollationKey getCollationKey(String source) {
        com.ibm.icu.text.CollationKey icuCollKey = fIcuCollator.getCollationKey(source);
        return CollationKeyICU.wrap(icuCollKey);
    }

    @Override
    public int getDecomposition() {
        int mode = java.text.Collator.NO_DECOMPOSITION;

        if (fIcuCollator.getStrength() == Collator.IDENTICAL) {
            return java.text.Collator.FULL_DECOMPOSITION;
        }
        int icuMode = fIcuCollator.getDecomposition();
        if (icuMode == Collator.CANONICAL_DECOMPOSITION) {
            mode = java.text.Collator.CANONICAL_DECOMPOSITION;
        }
//        else if (icuMode == Collator.NO_DECOMPOSITION) {
//            mode = java.text.Collator.NO_DECOMPOSITION;
//        }
//        else {
//            throw new IllegalStateException("Unknown decomposition mode is used by the ICU Collator.");
//        }

        return mode;
    }

    @Override
    public int getStrength() {
        int strength;
        int icuStrength = fIcuCollator.getStrength();
        switch (icuStrength) {
        case Collator.IDENTICAL:
            strength = java.text.Collator.IDENTICAL;
            break;
        case Collator.PRIMARY:
            strength = java.text.Collator.PRIMARY;
            break;
        case Collator.SECONDARY:
            strength = java.text.Collator.SECONDARY;
            break;
        case Collator.TERTIARY:
            strength = java.text.Collator.TERTIARY;
            break;
        case Collator.QUATERNARY:
            // Note: No quaternary support in Java..
            // Return tertiary instead for now.
            strength = java.text.Collator.TERTIARY;
            break;
        default:
            throw new IllegalStateException("Unknown strength is used by the ICU Collator.");
        }
        return strength;
    }

    @Override
    public int hashCode() {
        return fIcuCollator.hashCode();
    }

    @Override
    public void setDecomposition(int decompositionMode) {
        switch (decompositionMode) {
        case java.text.Collator.CANONICAL_DECOMPOSITION:
            fIcuCollator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
            break;
        case java.text.Collator.NO_DECOMPOSITION:
            fIcuCollator.setDecomposition(Collator.NO_DECOMPOSITION);
            break;
        case java.text.Collator.FULL_DECOMPOSITION:
            // Not supported by ICU.
            // This option is interpreted as IDENTICAL strength.
            fIcuCollator.setStrength(Collator.IDENTICAL);
            break;
        default:
            throw new IllegalArgumentException("Invalid decomposition mode.");
        }
    }

    @Override
    public void setStrength(int newStrength) {
        switch (newStrength) {
        case java.text.Collator.IDENTICAL:
            fIcuCollator.setStrength(Collator.IDENTICAL);
            break;
        case java.text.Collator.PRIMARY:
            fIcuCollator.setStrength(Collator.PRIMARY);
            break;
        case java.text.Collator.SECONDARY:
            fIcuCollator.setStrength(Collator.SECONDARY);
            break;
        case java.text.Collator.TERTIARY:
            fIcuCollator.setStrength(Collator.TERTIARY);
            break;
        default:
            throw new IllegalArgumentException("Invalid strength.");
        }
    }

}
