/*
 ****************************************************************************
 * Copyright (C) 2005-2006, International Business Machines Corporation and *
 * others. All Rights Reserved.                                             *
 ****************************************************************************
 *
 */
package com.ibm.icu.text;

import java.util.Arrays;

/**
 * CharsetRecognizer implemenation for Asian  - double or multi-byte - charsets.
 *                   Match is determined mostly by the input data adhering to the
 *                   encoding scheme for the charset, and, optionally,
 *                   frequency-of-occurence of characters.
 * <p/>
 *                   Instances of this class are singletons, one per encoding
 *                   being recognized.  They are created in the main
 *                   CharsetDetector class and kept in the global list of available
 *                   encodings to be checked.  The specific encoding being recognized
 *                   is determined by subclass.
 * 
 * @internal                  
 */
abstract class CharsetRecog_mbcs extends CharsetRecognizer {

   /**
     * Get the IANA name of this charset.
     * @return the charset name.
     */
    abstract String      getName() ;
    
    
    /**
     * Test the match of this charset with the input text data
     *      which is obtained via the CharsetDetector object.
     * 
     * @param det  The CharsetDetector, which contains the input text
     *             to be checked for being in this charset.
     * @return     Two values packed into one int  (Damn java, anyhow)
     *             <br/>
     *             bits 0-7:  the match confidence, ranging from 0-100
     *             <br/>
     *             bits 8-15: The match reason, an enum-like value.
     */
    int match(CharsetDetector det, int [] commonChars) {
        int   singleByteCharCount = 0;
        int   doubleByteCharCount = 0;
        int   commonCharCount     = 0;
        int   badCharCount        = 0;
        int   totalCharCount      = 0;
        int   confidence          = 0;
        iteratedChar   iter       = new iteratedChar();
        
        detectBlock: {
            for (iter.reset(); nextChar(iter, det);) {
                totalCharCount++;
                if (iter.error) {
                    badCharCount++; 
                } else {
                    
                    if (iter.charValue <= 0xff) {
                        singleByteCharCount++;
                    } else {
                        doubleByteCharCount++;
                        if (commonChars != null) {
                            if (Arrays.binarySearch(commonChars, iter.charValue) >= 0) {
                                commonCharCount++;
                            }
                        }
                    }
                }
                if (badCharCount >= 2 && badCharCount*5 >= doubleByteCharCount) {
                    // Bail out early if the byte data is not matching the encoding scheme.
                    break detectBlock;
                }
            }
            
            if (doubleByteCharCount <= 10 && badCharCount== 0) {
                // Not many multi-byte chars.
                //   ASCII or ISO file?  It's probably not our encoding,
                //   but is not incompatible with our encoding, so don't give it a zero.
                confidence = 10;
                break detectBlock;
            }
            
            //
            //  No match if there are too many characters that don't fit the encoding scheme.
            //    (should we have zero tolerance for these?)
            //
            if (doubleByteCharCount < 20*badCharCount) {
                confidence = 0;
                break detectBlock;
            }
            
            if (commonChars == null) {
                // We have no statistics on frequently occuring characters.
                //  Assess confidence purely on having a reasonable number of
                //  multi-byte characters (the more the better
                confidence = 30 + doubleByteCharCount - 20*badCharCount;
                if (confidence > 100) {
                    confidence = 100;
                }
            }else {
                //
                // Frequency of occurence statistics exist.
                //
                double maxVal = Math.log((float)doubleByteCharCount / 4);
                double scaleFactor = 90.0 / maxVal;
                confidence = (int)(Math.log(commonCharCount+1) * scaleFactor + 10);
                confidence = Math.min(confidence, 100);
            }
        }   // end of detectBlock:
        
        return confidence;
    }
    
     // "Character"  iterated character class.
     //    Recognizers for specific mbcs encodings make their "characters" available
     //    by providing a nextChar() function that fills in an instance of iteratedChar
     //    with the next char from the input.
     //    The returned characters are not converted to Unicode, but remain as the raw
     //    bytes (concatenated into an int) from the codepage data.
     //
     //  For Asian charsets, use the raw input rather than the input that has been
     //   stripped of markup.  Detection only considers multi-byte chars, effectively
     //   stripping markup anyway, and double byte chars do occur in markup too.
     //
     static class iteratedChar {
         int             charValue = 0;             // 1-4 bytes from the raw input data
         int             index     = 0;
         int             nextIndex = 0;
         boolean         error     = false;
         boolean         done      = false;
         
         void reset() {
             charValue = 0;
             index     = -1;
             nextIndex = 0;
             error     = false;
             done      = false;
         }
         
         int nextByte(CharsetDetector det) {
             if (nextIndex >= det.fRawLength) {
                 done = true;
                 return -1;
             }
             int byteValue = (int)det.fRawInput[nextIndex++] & 0x00ff;
             return byteValue;
         }       
     }
     
     /**
      * Get the next character (however many bytes it is) from the input data
      *    Subclasses for specific charset encodings must implement this function
      *    to get characters according to the rules of their encoding scheme.
      * 
      *  This function is not a method of class iteratedChar only because
      *   that would require a lot of extra derived classes, which is awkward.
      * @param it  The iteratedChar "struct" into which the returned char is placed.
      * @param det The charset detector, which is needed to get at the input byte data
      *            being iterated over.
      * @return    True if a character was returned, false at end of input.
      */
     abstract boolean nextChar(iteratedChar it, CharsetDetector det);
     


     
     
     /**
      *   Shift-JIS charset recognizer.   
      *
      */
     static class CharsetRecog_sjis extends CharsetRecog_mbcs {
         static int [] commonChars = 
             // TODO:  This set of data comes from the character frequency-
             //        of-occurence analysis tool.  The data needs to be moved
             //        into a resource and loaded from there.
            {0x8140, 0x8141, 0x8142, 0x8145, 0x815b, 0x8169, 0x816a, 0x8175, 0x8176, 0x82a0, 
             0x82a2, 0x82a4, 0x82a9, 0x82aa, 0x82ab, 0x82ad, 0x82af, 0x82b1, 0x82b3, 0x82b5, 
             0x82b7, 0x82bd, 0x82be, 0x82c1, 0x82c4, 0x82c5, 0x82c6, 0x82c8, 0x82c9, 0x82cc, 
             0x82cd, 0x82dc, 0x82e0, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82f0, 0x82f1, 0x8341, 
             0x8343, 0x834e, 0x834f, 0x8358, 0x835e, 0x8362, 0x8367, 0x8375, 0x8376, 0x8389, 
             0x838a, 0x838b, 0x838d, 0x8393, 0x8e96, 0x93fa, 0x95aa};
         
         boolean nextChar(iteratedChar it, CharsetDetector det) {
             it.index = it.nextIndex;
             it.error = false;
             int firstByte;
             firstByte = it.charValue = it.nextByte(det);
             if (firstByte < 0) {
                 return false;
             }
             
             if (firstByte <= 0x7f || (firstByte>0xa0 && firstByte<=0xdf)) {
                 return true;
             }
             
             int secondByte = it.nextByte(det);
             if (secondByte < 0)  {
                 return false;          
             }
             it.charValue = (firstByte << 8) | secondByte;
             if (! ((secondByte>=0x40 && secondByte<=0x7f) || (secondByte>=0x80 && secondByte<=0xff))) {
                 // Illegal second byte value.
                 it.error = true;
             }
             return true;
         }
         
         int match(CharsetDetector det) {
             return match(det, commonChars);
         }
         
         String getName() {
             return "Shift_JIS";
         }
         
         public String getLanguage()
         {
             return "ja";
         }

         
     }
     
     
     /**
      *   Big5 charset recognizer.   
      *
      */
     static class CharsetRecog_big5 extends CharsetRecog_mbcs {
         static int [] commonChars = 
             // TODO:  This set of data comes from the character frequency-
             //        of-occurence analysis tool.  The data needs to be moved
             //        into a resource and loaded from there.
            {0xa140, 0xa141, 0xa142, 0xa143, 0xa147, 0xa149, 0xa175, 0xa176, 0xa440, 0xa446, 
             0xa447, 0xa448, 0xa451, 0xa454, 0xa457, 0xa464, 0xa46a, 0xa46c, 0xa477, 0xa4a3, 
             0xa4a4, 0xa4a7, 0xa4c1, 0xa4ce, 0xa4d1, 0xa4df, 0xa4e8, 0xa4fd, 0xa540, 0xa548, 
             0xa558, 0xa569, 0xa5cd, 0xa5e7, 0xa657, 0xa661, 0xa662, 0xa668, 0xa670, 0xa6a8, 
             0xa6b3, 0xa6b9, 0xa6d3, 0xa6db, 0xa6e6, 0xa6f2, 0xa740, 0xa751, 0xa759, 0xa7da, 
             0xa8a3, 0xa8a5, 0xa8ad, 0xa8d1, 0xa8d3, 0xa8e4, 0xa8fc, 0xa9c0, 0xa9d2, 0xa9f3, 
             0xaa6b, 0xaaba, 0xaabe, 0xaacc, 0xaafc, 0xac47, 0xac4f, 0xacb0, 0xacd2, 0xad59, 
             0xaec9, 0xafe0, 0xb0ea, 0xb16f, 0xb2b3, 0xb2c4, 0xb36f, 0xb44c, 0xb44e, 0xb54c, 
             0xb5a5, 0xb5bd, 0xb5d0, 0xb5d8, 0xb671, 0xb7ed, 0xb867, 0xb944, 0xbad8, 0xbb44, 
             0xbba1, 0xbdd1, 0xc2c4, 0xc3b9, 0xc440, 0xc45f};
          
         boolean nextChar(iteratedChar it, CharsetDetector det) {
             it.index = it.nextIndex;
             it.error = false;
             int firstByte;
             firstByte = it.charValue = it.nextByte(det);
             if (firstByte < 0) {
                 return false;
             }
             
             if (firstByte <= 0x7f || firstByte==0xff) {
                 // single byte character.
                 return true;
             }
             
             int secondByte = it.nextByte(det);
             if (secondByte < 0)  {
                 return false;          
             }
             it.charValue = (it.charValue << 8) | secondByte;

             if (secondByte < 0x40 ||
                 secondByte ==0x7f ||
                 secondByte == 0xff) {
                     it.error = true;
             }
             return true;
         }
         
         int match(CharsetDetector det) {
             return match(det, commonChars);
         }
         
         String getName() {
             return "Big5";
         }
         
         
         public String getLanguage()
         {
             return "zh";
         }
     }
     
     
     /**
      *   EUC charset recognizers.  One abstract class that provides the common function
      *             for getting the next character according to the EUC encoding scheme,
      *             and nested derived classes for EUC_KR, EUC_JP, EUC_CN.   
      *
      */
     abstract static class CharsetRecog_euc extends CharsetRecog_mbcs {
         
         /*
          *  (non-Javadoc)
          *  Get the next character value for EUC based encodings.
          *  Character "value" is simply the raw bytes that make up the character
          *     packed into an int.
          */
         boolean nextChar(iteratedChar it, CharsetDetector det) {
             it.index = it.nextIndex;
             it.error = false;
             int firstByte  = 0;
             int secondByte = 0;
             int thirdByte  = 0;
             int fourthByte = 0;
             
             buildChar: {
                 firstByte = it.charValue = it.nextByte(det);                 
                 if (firstByte < 0) {
                     // Ran off the end of the input data
                     it.done = true;
                     break buildChar;
                 }
                 if (firstByte <= 0x8d) {
                     // single byte char
                     break buildChar;
                 }
                 
                 secondByte = it.nextByte(det);
                 it.charValue = (it.charValue << 8) | secondByte;
                 
                 if (firstByte >= 0xA1 && firstByte <= 0xfe) {
                     // Two byte Char
                     if (secondByte < 0xa1) {
                         it.error = true;
                     }
                     break buildChar;
                 }
                 if (firstByte == 0x8e) {
                     // Code Set 2.
                     //   In EUC-JP, total char size is 2 bytes, only one byte of actual char value.
                     //   In EUC-TW, total char size is 4 bytes, three bytes contribute to char value.
                     // We don't know which we've got.
                     // Treat it like EUC-JP.  If the data really was EUC-TW, the following two
                     //   bytes will look like a well formed 2 byte char.  
                     if (secondByte < 0xa1) {
                         it.error = true;
                     }
                     break buildChar;                     
                 }
                 
                 if (firstByte == 0x8f) {
                     // Code set 3.
                     // Three byte total char size, two bytes of actual char value.
                     thirdByte    = it.nextByte(det);
                     it.charValue = (it.charValue << 8) | thirdByte;
                     if (thirdByte < 0xa1) {
                         it.error = true;
                     }
                 }
              }
             
             return (it.done == false);
         }
         
         /**
          * The charset recognize for EUC-JP.  A singleton instance of this class
          *    is created and kept by the public CharsetDetector class
          */
         static class CharsetRecog_euc_jp extends CharsetRecog_euc {
             static int [] commonChars = 
                 // TODO:  This set of data comes from the character frequency-
                 //        of-occurence analysis tool.  The data needs to be moved
                 //        into a resource and loaded from there.
                {0xa1a1, 0xa1a2, 0xa1a3, 0xa1a6, 0xa1bc, 0xa1ca, 0xa1cb, 0xa1d6, 0xa1d7, 0xa4a2, 
                 0xa4a4, 0xa4a6, 0xa4a8, 0xa4aa, 0xa4ab, 0xa4ac, 0xa4ad, 0xa4af, 0xa4b1, 0xa4b3, 
                 0xa4b5, 0xa4b7, 0xa4b9, 0xa4bb, 0xa4bd, 0xa4bf, 0xa4c0, 0xa4c1, 0xa4c3, 0xa4c4, 
                 0xa4c6, 0xa4c7, 0xa4c8, 0xa4c9, 0xa4ca, 0xa4cb, 0xa4ce, 0xa4cf, 0xa4d0, 0xa4de, 
                 0xa4df, 0xa4e1, 0xa4e2, 0xa4e4, 0xa4e8, 0xa4e9, 0xa4ea, 0xa4eb, 0xa4ec, 0xa4ef, 
                 0xa4f2, 0xa4f3, 0xa5a2, 0xa5a3, 0xa5a4, 0xa5a6, 0xa5a7, 0xa5aa, 0xa5ad, 0xa5af, 
                 0xa5b0, 0xa5b3, 0xa5b5, 0xa5b7, 0xa5b8, 0xa5b9, 0xa5bf, 0xa5c3, 0xa5c6, 0xa5c7, 
                 0xa5c8, 0xa5c9, 0xa5cb, 0xa5d0, 0xa5d5, 0xa5d6, 0xa5d7, 0xa5de, 0xa5e0, 0xa5e1, 
                 0xa5e5, 0xa5e9, 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5f3, 0xb8a9, 0xb9d4, 0xbaee, 
                 0xbbc8, 0xbef0, 0xbfb7, 0xc4ea, 0xc6fc, 0xc7bd, 0xcab8, 0xcaf3, 0xcbdc, 0xcdd1};             
             String getName() {
                 return "EUC-JP";
             }
             
             int match(CharsetDetector det) {
                 return match(det, commonChars);
             }
             
             public String getLanguage()
             {
                 return "ja";
             }
         }
         
         /**
          * The charset recognize for EUC-KR.  A singleton instance of this class
          *    is created and kept by the public CharsetDetector class
          */
         static class CharsetRecog_euc_kr extends CharsetRecog_euc {
             static int [] commonChars = 
                 // TODO:  This set of data comes from the character frequency-
                 //        of-occurence analysis tool.  The data needs to be moved
                 //        into a resource and loaded from there.
                {0xb0a1, 0xb0b3, 0xb0c5, 0xb0cd, 0xb0d4, 0xb0e6, 0xb0ed, 0xb0f8, 0xb0fa, 0xb0fc, 
                 0xb1b8, 0xb1b9, 0xb1c7, 0xb1d7, 0xb1e2, 0xb3aa, 0xb3bb, 0xb4c2, 0xb4cf, 0xb4d9, 
                 0xb4eb, 0xb5a5, 0xb5b5, 0xb5bf, 0xb5c7, 0xb5e9, 0xb6f3, 0xb7af, 0xb7c2, 0xb7ce, 
                 0xb8a6, 0xb8ae, 0xb8b6, 0xb8b8, 0xb8bb, 0xb8e9, 0xb9ab, 0xb9ae, 0xb9cc, 0xb9ce, 
                 0xb9fd, 0xbab8, 0xbace, 0xbad0, 0xbaf1, 0xbbe7, 0xbbf3, 0xbbfd, 0xbcad, 0xbcba, 
                 0xbcd2, 0xbcf6, 0xbdba, 0xbdc0, 0xbdc3, 0xbdc5, 0xbec6, 0xbec8, 0xbedf, 0xbeee, 
                 0xbef8, 0xbefa, 0xbfa1, 0xbfa9, 0xbfc0, 0xbfe4, 0xbfeb, 0xbfec, 0xbff8, 0xc0a7, 
                 0xc0af, 0xc0b8, 0xc0ba, 0xc0bb, 0xc0bd, 0xc0c7, 0xc0cc, 0xc0ce, 0xc0cf, 0xc0d6, 
                 0xc0da, 0xc0e5, 0xc0fb, 0xc0fc, 0xc1a4, 0xc1a6, 0xc1b6, 0xc1d6, 0xc1df, 0xc1f6, 
                 0xc1f8, 0xc4a1, 0xc5cd, 0xc6ae, 0xc7cf, 0xc7d1, 0xc7d2, 0xc7d8, 0xc7e5, 0xc8ad};
             
             String getName() {
                 return "EUC-KR";
             }
             
             int match(CharsetDetector det) {
                 return match(det, commonChars);
             }
             
             public String getLanguage()
             {
                 return "ko";
             }
         }
     }
     
     /**
      * 
      *   GB-18030 recognizer. Uses simplified Chinese statistics.   
      *
      */
     static class CharsetRecog_gb_18030 extends CharsetRecog_mbcs {
         
         /*
          *  (non-Javadoc)
          *  Get the next character value for EUC based encodings.
          *  Character "value" is simply the raw bytes that make up the character
          *     packed into an int.
          */
         boolean nextChar(iteratedChar it, CharsetDetector det) {
             it.index = it.nextIndex;
             it.error = false;
             int firstByte  = 0;
             int secondByte = 0;
             int thirdByte  = 0;
             int fourthByte = 0;
             
             buildChar: {
                 firstByte = it.charValue = it.nextByte(det); 
                 
                 if (firstByte < 0) {
                     // Ran off the end of the input data
                     it.done = true;
                     break buildChar;
                 }
                 
                 if (firstByte <= 0x80) {
                     // single byte char
                     break buildChar;
                 }
                 
                 secondByte = it.nextByte(det);
                 it.charValue = (it.charValue << 8) | secondByte;
                 
                 if (firstByte >= 0x81 && firstByte <= 0xFE) {
                     // Two byte Char
                     if ((secondByte >= 0x40 && secondByte <= 0x7E) || (secondByte >=80 && secondByte <=0xFE)) {
                         break buildChar;
                     }
                     
                     // Four byte char
                     if (secondByte >= 0x30 && secondByte <= 0x39) {
                         thirdByte = it.nextByte(det);
                         
                         if (thirdByte >= 0x81 && thirdByte <= 0xFE) {
                             fourthByte = it.nextByte(det);
                             
                             if (fourthByte >= 0x30 && fourthByte <= 0x39) {
                                 it.charValue = (it.charValue << 16) | (thirdByte << 8) | fourthByte;
                                 break buildChar;
                             }
                         }
                     }
                     
                     it.error = true;
                     break buildChar;
                 }
             }
                 
             return (it.done == false);
         }
         
         static int [] commonChars = 
             // TODO:  This set of data comes from the character frequency-
             //        of-occurence analysis tool.  The data needs to be moved
             //        into a resource and loaded from there.
            {0xa1a1, 0xa1a2, 0xa1a3, 0xa1a4, 0xa1b0, 0xa1b1, 0xa1f1, 0xa1f3, 0xa3a1, 0xa3ac, 
             0xa3ba, 0xb1a8, 0xb1b8, 0xb1be, 0xb2bb, 0xb3c9, 0xb3f6, 0xb4f3, 0xb5bd, 0xb5c4, 
             0xb5e3, 0xb6af, 0xb6d4, 0xb6e0, 0xb7a2, 0xb7a8, 0xb7bd, 0xb7d6, 0xb7dd, 0xb8b4, 
             0xb8df, 0xb8f6, 0xb9ab, 0xb9c9, 0xb9d8, 0xb9fa, 0xb9fd, 0xbacd, 0xbba7, 0xbbd6, 
             0xbbe1, 0xbbfa, 0xbcbc, 0xbcdb, 0xbcfe, 0xbdcc, 0xbecd, 0xbedd, 0xbfb4, 0xbfc6, 
             0xbfc9, 0xc0b4, 0xc0ed, 0xc1cb, 0xc2db, 0xc3c7, 0xc4dc, 0xc4ea, 0xc5cc, 0xc6f7, 
             0xc7f8, 0xc8ab, 0xc8cb, 0xc8d5, 0xc8e7, 0xc9cf, 0xc9fa, 0xcab1, 0xcab5, 0xcac7, 
             0xcad0, 0xcad6, 0xcaf5, 0xcafd, 0xccec, 0xcdf8, 0xceaa, 0xcec4, 0xced2, 0xcee5, 
             0xcfb5, 0xcfc2, 0xcfd6, 0xd0c2, 0xd0c5, 0xd0d0, 0xd0d4, 0xd1a7, 0xd2aa, 0xd2b2, 
             0xd2b5, 0xd2bb, 0xd2d4, 0xd3c3, 0xd3d0, 0xd3fd, 0xd4c2, 0xd4da, 0xd5e2, 0xd6d0};

         
         String getName() {
             return "GB18030";
         }
         
         int match(CharsetDetector det) {
             return match(det, commonChars);
         }
         
         public String getLanguage()
         {
             return "zh";
         }
     }
     
     
}
