using System;
using System.Collections;
using System.IO;
using System.Text;
 
namespace HXBTools.Util
{
 /**//// <summary>
 /// 用于将一个数值型转化为汉语的读法.
 /// </summary>
 public class NumberToChn
 {
  public NumberToChn()
  {
   //
   // TODO: 在此处添加构造函数逻辑
   //
  }
 
  public static string GetChn(decimal dc, bool bUpper)
  {
   return GetChn(dc.ToString(), bUpper);
  }
 
  public static string GetChn(int i, bool bUpper)
  {
   return GetChn(i.ToString(), bUpper);
  }
 
  public static string GetChn(long l, bool bUpper)
  {
   return GetChn(l.ToString(), bUpper);
  }        
 
  public static string GetRMBChn(string sDigital, bool bUpper)
  {
   // 找出第一个点所在的位置,之前的部分用getchn来处理,之后的部分自已处理.
   if (sDigital == null | sDigital.Length == 0)
    return "";
 
   int iIndex = sDigital.IndexOf(".");
   string sIntPart;
   string sDecPart;
   if (iIndex == -1)
   {
    sIntPart = sDigital;
    sDecPart = "";
   }
   else
   {
    sIntPart = sDigital.Substring(0, iIndex);
    sDecPart = sDigital.Substring(iIndex+1);
   }
 
   StringBuilder sb = new StringBuilder(sDigital.Length * 2 + 10);
   foreach(char c in sDecPart)
   {
    if ( char.IsDigit(c))
    {
     sb.Append(c);
    }
   }
   sDecPart = sb.ToString();
   sb.Length = 0;
 
   string sTmp = GetChn(sIntPart, bUpper);
   if (sTmp != "零" && sTmp.Length != 0)
   {
    sb.Append(sTmp);
    sb.Append(bUpper?'园':'元');            
   }
            
   bool bPrevIsZero = false;
   if (sIntPart.Length > 0 && sIntPart.EndsWith("0") && sb.Length > 1)
   {
    bPrevIsZero = true;
   }
   for (int i = 0; i < sDecPart.Length && i < arRMBRight.Length; i ++)
   {
    if (sDecPart[i] == '0')
    {
     bPrevIsZero = true;
    }
    else
    {
     if (bPrevIsZero == true)
     {
      sb.Append('零');
      bPrevIsZero = false;
     }
     sb.Append(bUpper?arDigitals2[sDecPart[i] - '0']:arDigitals[sDecPart[i] - '0']);
     sb.Append(arRMBRight[i]);
    }
   }
   if (sb.Length > 0)
   {
    sb.Append('整');
   }
   else
   {
    sb.Append(bUpper?"零园整":"零元整");
   }
   return sb.ToString();
  }
 
  public static string GetChn(string s, bool bUpper)
  {
   // 先将s过滤,删除所有的非数字字符。
   if (s == null || s.Trim().Length == 0)
    return "";
   StringBuilder sb = new StringBuilder(s.Length);
   int iPointCount = 0;
   for(int i = 0; i < s.Length; i ++)
   {
    char c = s[i];
    if (Char.IsDigit(c))
    {
     sb.Append(c);
    }
    else if (c == '.')
    {
     // 如果是第二个之后的点,那么不管了。
     if (iPointCount == 0)
     {
      sb.Append(c);
      iPointCount ++;
     }                                        
    }
    else if( c == '-' && i == 0) 
    {
     sb.Append(c);
    }
    else
    {
     // 省下的全部忽略
    }
   }
 
   string sDigital = sb.ToString();
   if (sDigital.EndsWith("."))
   {
    sDigital = sDigital.Substring(0,sDigital.Length - 1);
   }
   if (sDigital.Length == 0)
   {
    sDigital = "0";
   }
            
   sb.Length = 0; // 留为后用。
            
   // 从小数点前后分为两部分
   int iTmp = sDigital.IndexOf('.');
   string sIntPart;
   string sDecimalPart;
   if (iTmp == -1)
   {
    sIntPart = sDigital;
    sDecimalPart = "";
   }
   else
   {
    sIntPart = sDigital.Substring(0, iTmp);
    sDecimalPart = sDigital.Substring(iTmp+1);
   }
 
   // 处理小数点之前的部分
 
   // 先决定最高位是什么位,再依次地向后拼出。
   // 大循环是亿的个数, 小循环是万的个数。
            
   sb = new StringBuilder(sDigital.Length * 2 + 6);
   if (sDigital.StartsWith("-"))
   {
    sb.Append("负");
    sIntPart = sIntPart.Substring(1);
   }
   // 如果小数点之后没有内容,之前部分又是空,那么不输出.
   if (sIntPart.Length == 0 && sDecimalPart.Length == 0)
   {
    return "";
   }
 
   int iBitCntInWan = 0;
   bool bPrevIs0 = false;
   int iWanNotZeroCnt = 0;
   int iNotZeroCnt = 0;
 
   for (int i = 0; i < sIntPart.Length; i ++)
   {
    int iBitCnt = sIntPart.Length - i -1;
 
    char cNum = sIntPart[i];
    if (cNum == '0')
    {
     // 如果是零,那么不处理
     bPrevIs0 = true;
    }
    else
    {
     if (bPrevIs0)
     {
      // 如果上一个是0
      if(iNotZeroCnt > 0)
      {
       //如果不是第一个字 那么加一个零字                                    
       sb.Append(bUpper?arDigitals2[0]:arDigitals[0]);
      }                                
     }
     iWanNotZeroCnt ++;
     iNotZeroCnt ++;
 
     bPrevIs0 = false;
     sb.Append(bUpper?arDigitals2[cNum - '0']:arDigitals[cNum - '0']);    // 加数名
     iBitCntInWan = iBitCnt % 4;
     if (iBitCntInWan != 0)
     {
      sb.Append(bUpper?arRights2[iBitCntInWan]:arRights[iBitCntInWan]);    // 加权名
     }
    }
 
    if (iBitCnt % 8 == 0)
    {
     // 遇亿的处理
     if (iBitCnt / 8 >= 1 && iNotZeroCnt > 0 )
      sb.Append('亿');
     bPrevIs0 = false;
     iWanNotZeroCnt = 0;
    }
    else if (iBitCnt % 4 == 0)
    {
     // 遇万位的处理
     if ((iBitCnt % 8)/4 >= 1 && iWanNotZeroCnt > 0 )
     {
      sb.Append('万');
     }
     bPrevIs0 = false;
     iWanNotZeroCnt = 0;
    }
   }
 
 
   // 如果全部都是0,那么输出一个"零".
   if (iNotZeroCnt == 0)
   {
    sb.Append("零");
   }            
 
   // 处理小数点之后的部分
   if(sDecimalPart.Length != 0)
   {
    sb.Append("点");
    for(int i = 0;  i < sDecimalPart.Length; i ++)
    {
     sb.Append(bUpper?arDigitals2[sDecimalPart[i]-'0']:arDigitals[sDecimalPart[i]-'0']);
    }
   }
   iTmp = 0;
   if (sb[0] == '负')
   {
    iTmp =1;
   }
 
   // 把起头的"一十"改为"拾".
   if (sb.Length >= 2)
   {
    if (sb[iTmp] == (bUpper?arDigitals2[1]:arDigitals[1]) && 
     sb[iTmp + 1] == (bUpper?arRights2[1]:arRights[1]))
    {
     sb.Remove(iTmp,1);
    }
   }
   return sb.ToString();
  }
 
  private static char [] arRights = {' ', '十', '百', '千'}; // 权名
  private static char [] arRights2 = {' ', '拾', '佰', '仟'}; // 权名
 
  private static char [] arDigitals = {
            '零','一','二','三','四','五','六','七','八','九'
           };
  private static char [] arDigitals2= {
            '零','壹','贰','叁','肆','伍','陆','柒','捌','玖'
           };
 
  private static char [] arRMBRight = {'角', '分', '厘', '毫', '丝'};
 
 }
}