namespace Barcode
{
/// <summary>
/// Code39:生成39条形码。
/// </summary>
public class Code39
{
    //对应码表
    private Hashtable Decode;
    private Hashtable CheckCode;
    //每个字符间的间隔符
    private string SPARATOR="0";
    //float WidthUNIT= 0.25f;//宽度单位 mm
    public int WidthCU = 3;    //粗线和宽间隙宽度
    public int WidthXI = 1;    //细线和窄间隙宽度
    public int xCoordinate =10;//75;    //条码起始坐标
    public int LineHeight=60;
    private int Height=0;
    private int Width=0;

    public Code39()
    {
     Decode=new Hashtable();
     Decode.Add("0","000110100");
     Decode.Add("1","100100001");
     Decode.Add("2","001100001");
     Decode.Add("3","101100000");
     Decode.Add("4","000110001");
     Decode.Add("5","100110000");
     Decode.Add("6","001110000");
     Decode.Add("7","000100101");
     Decode.Add("8","100100100");
     Decode.Add("9","001100100");
     Decode.Add("A","100001001");
     Decode.Add("B","001001001");
     Decode.Add("C","101001000");
     Decode.Add("D","000011001");
     Decode.Add("E","100011000");
     Decode.Add("F","001011000");
     Decode.Add("G","000001101");
     Decode.Add("H","100001100");
     Decode.Add("I","001001101");
     Decode.Add("J","000011100");
     Decode.Add("K","100000011");
     Decode.Add("L","001000011");
     Decode.Add("M","101000010");
     Decode.Add("N","000010011");
     Decode.Add("O","100010010");
     Decode.Add("P","001010010");
     Decode.Add("Q","000000111");
     Decode.Add("R","100000110");
     Decode.Add("S","001000110");
     Decode.Add("T","000010110");
     Decode.Add("U","110000001");
     Decode.Add("V","011000001");
     Decode.Add("W","111000000");
     Decode.Add("X","010010001");
     Decode.Add("Y","110010000");
     Decode.Add("Z","011010000");
     Decode.Add("-","010000101");
     Decode.Add("%","000101010");
     Decode.Add("$","010101000");
     Decode.Add("*","010010100");

     CheckCode=new Hashtable();
     CheckCode.Add("0","0");
     CheckCode.Add("1","1");
     CheckCode.Add("2","2");
     CheckCode.Add("3","3");
     CheckCode.Add("4","4");
     CheckCode.Add("5","5");
     CheckCode.Add("6","6");
     CheckCode.Add("7","7");
     CheckCode.Add("8","8");
     CheckCode.Add("9","9");
     CheckCode.Add("A","10");
     CheckCode.Add("B","11");
     CheckCode.Add("C","12");
     CheckCode.Add("D","13");
     CheckCode.Add("E","14");
     CheckCode.Add("F","15");
     CheckCode.Add("G","16");
     CheckCode.Add("H","17");
     CheckCode.Add("I","18");
     CheckCode.Add("J","19");
     CheckCode.Add("K","20");
     CheckCode.Add("L","21");
     CheckCode.Add("M","22");
     CheckCode.Add("N","23");
     CheckCode.Add("O","24");
     CheckCode.Add("P","25");
     CheckCode.Add("Q","26");
     CheckCode.Add("R","27");
     CheckCode.Add("S","28");
     CheckCode.Add("T","29");
     CheckCode.Add("U","30");
     CheckCode.Add("V","31");
     CheckCode.Add("W","32");
     CheckCode.Add("X","33");
     CheckCode.Add("Y","34");
     CheckCode.Add("Z","35");
     CheckCode.Add("-","36");
     CheckCode.Add(".","37");
     CheckCode.Add(",","38");
     CheckCode.Add("$","39");
     CheckCode.Add("/","40");
     CheckCode.Add("+","41");
     CheckCode.Add("%","42");
    }
    //保存文件
    public Boolean saveFile(string Code,string Title,int UseCheck)
    {
     string code39=Encode39(Code,UseCheck);
     if(code39!=null)
     {
      Bitmap saved=new Bitmap(this.Width,this.Height);
      Graphics g=Graphics.FromImage(saved);
      g.FillRectangle(new SolidBrush(Color.White),0,0,this.Width,this.Height);
      this.DrawBarCode39(code39,Title,g);
      //string path=ConfigurationSettings.AppSettings["ImagePath"];
      string path="C:\\";
      string filename=path+Code+".jpg";
      saved.Save(filename,ImageFormat.Jpeg);
      saved.Dispose();
      return true;
     }
     return false;
    }
    /***
    * Code:未经编码的字符串
    *
    * **/
    private string Encode39(string Code,int UseCheck)
    {
     int UseStand = 1;    //检查输入待编码字符是否为标准格式(是否以*开始结束)

     //保存备份数据
     string OriginalCode=Code;

     //为空不进行编码
     if(null==Code||Code.Trim().Equals(""))
     {
      return null;
     }
     //检查错误字符
     Code = Code.ToUpper();    //转为大写
     Regex rule = new Regex(@"[^0-9A-Z%$\-*]");
     if(rule.IsMatch(Code))
     {
      MessageBox.Show("编码中包含非法字符,目前仅支持字母,数字及%$-*符号!!");
      return null;
     }    
     //计算检查码
     if (UseCheck==1)
     {
      int Check = 0;
      //累计求和
      for (int i = 0; i < Code.Length; i++)
      {
       Check += int.Parse((string)CheckCode[Code.Substring(i,1)]);
      }
      //取模
      Check=Check%43;
      //附加检测码
      foreach(DictionaryEntry de in CheckCode)
      {
       if((string)de.Value==Check.ToString())
       {
        Code=Code+(string)de.Key;
        break;
       }
      }
     }
     //标准化输入字符,增加起始标记
     if (UseStand==1)
     {
      if (Code.Substring(0,1) != "*")
      {
       Code = "*" + Code;
      }
      if (Code.Substring(Code.Length-1,1)!="*")
      {
       Code = Code + "*";
      }
     }
     //转换成39编码
     string Code39="";
     for (int i = 0; i < Code.Length; i++)
     {
      Code39=Code39+(string)Decode[Code.Substring(i,1)]+SPARATOR;
     }

     int height = 30+LineHeight;//定义图片高度      
     int width=xCoordinate;
     for(int i=0;i<Code39.Length;i++)
     {
      if("0".Equals(Code39.Substring(i,1)))
      {
       width+=WidthXI;
      }
      else
      {
       width+=WidthCU;
      }
     }
     this.Width=width+xCoordinate;
     this.Height=height;

     return Code39;
    }

    private    void DrawBarCode39(string Code39,string Title,Graphics g)
    {
     int UseTitle = 1;    //条码上端显示标题
     //int UseTTF = 1;    //使用TTF字体,方便显示中文,需要$UseTitle=1时才能生效
     if(Title.Trim().Equals(""))
     {
      UseTitle=0;
     }
     Pen pWhite=new Pen(Color.White, 1);
     Pen pBlack=new Pen(Color.Black, 1);
     int position=xCoordinate;
     for(int i=0;i<Code39.Length;i++)
     {
      //绘制条线
      if("0".Equals(Code39.Substring(i,1)))
      {
       for(int j=0;j<WidthXI;j++)
       {
        g.DrawLine(pBlack,position+j,5,position+j,5+LineHeight);
       }
       position+=WidthXI;
      }
      else
      {
       for(int j=0;j<WidthCU;j++)
       {
        g.DrawLine(pBlack,position+j,5,position+j,5+LineHeight);
       }
       position+=WidthCU;
      }
      i++;
      //绘制间隔线
      if("0".Equals(Code39.Substring(i,1)))
      {
        position+=WidthXI;
      }
      else
      {
        position+=WidthCU;
      }
     }

     //显示标题
     if(UseTitle==1)
     {
      Font TitleFont=new Font("宋体", 16, FontStyle.Bold);
      SizeF sf=g.MeasureString(Title,TitleFont);
      g.DrawString(Title,TitleFont, Brushes.Black,(Width-sf.Width)/2,LineHeight+5);
     }

     return ;
    }

}
}