/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.fukurou.mail;

// import java.io.InputStream;
// import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
// import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
// import java.io.IOException;

// import javax.activation.DataHandler;
// import javax.activation.DataSource;
// import javax.mail.internet.InternetAddress;
// import javax.mail.internet.MimeMessage;
// import javax.mail.internet.MimeUtility;
// import javax.mail.MessagingException;
// import com.sun.mail.util.BASE64EncoderStream;

// import java.nio.charset.Charset;		// 5.5.2.6 (2012/05/25)

/**
 * 文字関係のコンバータです。
 * 一部コードのオリジナルは <a href="http://www-cms.phys.s.u-tokyo.ac.jp/~naoki/CIPINTRO/CCGI/kanjicod.html">Japanese Kanji Code</a>にて公開されているものです。
 * また、http://www.sk-jp.com/cgi-bin/treebbs.cgi?kako=1&amp;all=644&amp;s=681
 * にて YOSI さんが公開されたコードも参考にしています(というか実質同じです)。
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
class CharCodeConverter {
	private static final byte[] SJIS_KANA;	// 5.1.9.0 (2010/09/01) public ⇒ private へ変更

	/**
	 * インスタンスの生成を抑止します。
	 */
	private CharCodeConverter() {
		// 何もありません。(PMD エラー回避)
	}

	static {
		try {
			// 全角への変換テーブル
			SJIS_KANA = "。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゛゜".getBytes("Shift_JIS");
		} catch( UnsupportedEncodingException ex ) {
			throw new RuntimeException( "CANT HAPPEN",ex );
		}
	}

	/**
	 * Shift_JIS エンコーディングスキームに基づくバイト列を
	 * ISO-2022-JP エンコーディングスキームに変換します。
	 * 「半角カナ」は対応する全角文字に変換します。
	 *
	 * @param sjisBytes byte[] エンコードするShift_JISバイト配列
	 *
	 * @return byte[] 変換後のISO-2022-JP(JIS)バイト配列(not null)
	 */
	public static byte[] sjisToJis( final byte[] sjisBytes ) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		boolean nonAscii = false;
		int len = sjisBytes.length;
		for(int i = 0; i < len; i++ ) {
			if(sjisBytes[i] >= 0) {
				if(nonAscii) {
					nonAscii = false;
					out.write(0x1b);
					out.write('(');
					out.write('B');
				}
				out.write(sjisBytes[i]);
			} else {
				if(!nonAscii) {
					nonAscii = true;
					out.write(0x1b);
					out.write('$');
					out.write('B');
				}
				int bt = sjisBytes[i] & 0xff;
				if(bt >= 0xa1 && bt <= 0xdf) {
					// 半角カナは全角に変換
					int kanaIndex = (bt - 0xA1) * 2;
					sjisToJis(out, SJIS_KANA[kanaIndex], SJIS_KANA[kanaIndex + 1]);
				} else {
					i++;
					if(i == len) { break; }
					sjisToJis(out, sjisBytes[i - 1], sjisBytes[i]);
				}
			}
		}
		if(nonAscii) {
			out.write(0x1b);
			out.write('(');
			out.write('B');
		}
		return out.toByteArray();
	}

	/**
	 * １文字の２バイト Shift_JIS コードを JIS コードに変換して書き出します。
	 */
	private static void sjisToJis(
				final ByteArrayOutputStream out, final byte bhi, final byte blo) {
		int hi = (bhi << 1) & 0xFF;
		int lo = blo & 0xFF;
		if(lo < 0x9F) {
			if(hi < 0x3F) { hi += 0x1F; } else { hi -= 0x61; }
			if(lo > 0x7E) { lo -= 0x20; } else { lo -= 0x1F; }
		} else {
			if(hi < 0x3F) { hi += 0x20; } else { hi -= 0x60; }
			lo -= 0x7E;
		}
		out.write(hi);
		out.write(lo);
	}
}
