public interface CardDao {
	public List<CardBaseDTO> getCardBase(int cardBaseId) throws SQLException;

	public CardLayerDTO getCardLayer(int cardLayerId) throws SQLException;
	
	public CardDTO getCard(int cardId) throws SQLException;
	
	public List<Integer> getCardIdList() throws SQLException;
}
 public interface ImagDao {
	public BufferedImage getImage(String imagPath) throws IOException;
	
	public BufferedImage getImageWithoutSplit(String texbPath) throws IOException;
	
	public String getRefTextureFilePath(String imagPath) throws IOException;
	
	public List<String> getImagList();
	
	public List<String> getTexbList();
}
 public interface UnitDao {
	public List<Integer> getUnitIdList() throws SQLException;

	public List<Integer> getUnitNumList() throws SQLException;

	public UnitDTO getUnitById(int id) throws SQLException;

	public UnitDTO getUnitByNum(int num) throws SQLException;

	public List<UnitDTO> getAllUnits() throws SQLException;

	public String getAttrName(int attrId) throws SQLException;

	public String getRarityName(int rarityId) throws SQLException;

	public LeaderSkillDTO getLeaderSkill(int leaderSkillId) throws SQLException;

	public SkillDTO getSkill(int skillId) throws SQLException;

	public List<SkillLevelDetailDTO> getSkillLevelDetail(int skillId) throws SQLException;

	public String getUnitNaviAsset(int unitNaviAssetId) throws SQLException;

	public String getSkillEffectTypeName(int skillEffectType);

	public String getSkillTriggerTypeName(int triggerType);

	public String getUnitNameImgPath(int attrId) throws SQLException;

}
 public class CardDaoImpl implements CardDao {
	private String dbPath;
	private Connection conn;

	public CardDaoImpl() throws ClassNotFoundException, SQLException, FileNotFoundException {
		dbPath = SIFConfig.getInstance().get(ConfigName.dbPath);
		File cardDbFile = new File(new File(dbPath), "unit/card.db_");
		if (!cardDbFile.exists()) {
			throw new FileNotFoundException(cardDbFile.getAbsolutePath() + " doesn't exist!");
		}
		dbPath = cardDbFile.getAbsolutePath();
		conn = SqlLiteConnection.getInstance().getConnection(dbPath);
	}

	@Override
	public List<CardBaseDTO> getCardBase(int cardBaseId) throws SQLException {
		List<CardBaseDTO> list = new ArrayList<CardBaseDTO>(10);
		PreparedStatement preStatement = conn
				.prepareStatement("select * from card_base_m where card_base_id=?");
		preStatement.setInt(1, cardBaseId);
		ResultSet rs = preStatement.executeQuery();
		while (rs.next()) {
			CardBaseDTO dto = new CardBaseDTO();
			dto.setCardBaseId(cardBaseId);
			dto.setLayerOrder(rs.getInt("layer_order"));
			dto.setCardLayerId(rs.getInt("card_layer_id"));
			list.add(dto);
		}
		return list;
	}

	@Override
	public CardLayerDTO getCardLayer(int cardLayerId) throws SQLException {
		PreparedStatement preStatement = conn
				.prepareStatement("select * from card_layer_m where card_layer_id=?");
		preStatement.setInt(1, cardLayerId);
		ResultSet rs = preStatement.executeQuery();
		if (rs.next()) {
			CardLayerDTO dto = new CardLayerDTO();
			dto.setCardLayerId(cardLayerId);
			dto.setCardLayerAsset(rs.getString("card_layer_asset"));
			return dto;
		}
		return null;
	}

	@Override
	public CardDTO getCard(int cardId) throws SQLException {
		PreparedStatement preStatement = conn
				.prepareStatement("select * from card_m where card_id=?");
		preStatement.setInt(1, cardId);
		ResultSet rs = preStatement.executeQuery();
		if (rs.next()) {
			CardDTO dto = new CardDTO();
			dto.setCardId(cardId);
			dto.setCardBaseId(rs.getInt("card_base_id"));
			dto.setUnitNaviAssetId(rs.getInt("unit_navi_asset_id"));
			dto.setNaviLayerOrder(2);
			dto.setNaviRotation(rs.getInt("navi_rotation"));
			dto.setNaviMoveX(rs.getInt("navi_move_x"));
			dto.setNaviMoveY(rs.getInt("navi_move_y"));
			dto.setNaviSizeRatio(rs.getDouble("navi_size_ratio"));
			dto.setFlashAsset(rs.getString("flash_asset"));
			return dto;
		}
		return null;
	}

	@Override
	public List<Integer> getCardIdList() throws SQLException {
		List<Integer> list = new ArrayList<Integer>();
		PreparedStatement preStatement = conn.prepareStatement("select card_id from card_m");
		ResultSet rs = preStatement.executeQuery();
		while (rs.next()) {
			Integer i = new Integer(rs.getInt("card_id"));
			list.add(i);
		}
		return list;
	}
}
 public class ImagDaoImpl implements ImagDao {
	private static final Logger logger = LoggerFactory.getLogger(ImagDaoImpl.class);
	private File tempDir = new File("temp");
	private String imagPath;

	public ImagDaoImpl() {
		if (!tempDir.exists()) {
			tempDir.mkdir();
		}
	}

	private String readString(DataInputStream dis, int len) throws IOException {
		byte[] b = new byte[len];
		dis.read(b, 0, len);
		return new String(b);
	}

	private byte[] getBitmap(DataInputStream dis) throws IOException {
		byte[] b = new byte[1024];
		int len = 0;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		DataOutputStream dos = new DataOutputStream(baos);
		while ((len = dis.read(b)) != -1) {
			dos.write(b, 0, len);
		}
		return baos.toByteArray();
	}

	private byte[] decompress(byte[] data) {
		byte[] output = new byte[0];
		Inflater decompresser = new Inflater();
		decompresser.reset();
		decompresser.setInput(data);
		ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);
		try {
			byte[] buf = new byte[1024];
			while (!decompresser.finished()) {
				int i = decompresser.inflate(buf);
				o.write(buf, 0, i);
			}
			output = o.toByteArray();
		} catch (Exception e) {
			output = data;
			e.printStackTrace();
		} finally {
			try {
				o.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		decompresser.end();
		return output;
	}

	private BufferedImage splitImage(Texb texture, BufferedImage image) {
		BufferedImage cache = null;
		for (Timg img : texture.image) {
			long x1 = img.vertices[0].u;
			long y1 = img.vertices[0].v;
			long x2 = img.vertices[img.vertexLen - 1].u;
			long y2 = img.vertices[img.vertexLen - 1].v;
			BufferedImage bimg = image.getSubimage((int) x1, (int) y1, (int) (x2 - x1),
					(int) (y2 - y1));
			String pngPath = img.path.replaceAll("\\.imag.*$", "");
			File pngFile = new File(tempDir, pngPath);
			System.out.println(pngFile.getAbsolutePath());
			pngFile.getParentFile().mkdirs();
			try {
				ImageIO.write(bimg, "png", pngFile);
			} catch (IOException e) {
				logger.error("{} temp file write error.", pngFile.getAbsolutePath());
				e.printStackTrace();
				continue;
			}
			if (img.path.contains(this.imagPath)) {
				cache = bimg;
			} else {
				logger.debug("{}:{}", img.path, this.imagPath);
			}
		}
		return cache;
	}

	private Texb extractTexb(String texbPath) throws IOException {
		// 构造texb文件的位置
		String assetsPath = SIFConfig.getInstance().get(ConfigName.assetsPath);
		File root = new File(assetsPath).getParentFile();
		File texbFile = new File(root, texbPath);
		logger.info("Extract Texture: {}", texbFile.getAbsolutePath());
		// 解压Texb文件
		Texb t = new Texb();
		FileInputStream texbFile_;
		try{
			texbFile_ = new FileInputStream(texbFile);
		}catch(FileNotFoundException e){
			logger.info("Can't find image in external, searching in install...");
			root = new File(assetsPath.replace("external", "install")).getParentFile();
			texbFile = new File(root, texbPath);
			texbFile_ = new FileInputStream(texbFile);
		}
		DataInputStream dis = new DataInputStream(texbFile_);
		t.tag = readString(dis, 4);
		t.size = dis.readInt();
		t.pathLen = dis.readUnsignedShort();
		t.path = readString(dis, t.pathLen).replaceAll("^T", "").trim();
		t.canvasWidth = dis.readUnsignedShort();
		t.canvasHeight = dis.readUnsignedShort();
		dis.skipBytes(1);

		byte attrFlag = dis.readByte();
		t.imgType = Texb.IMG_TYPE[(attrFlag & 0x07)];
		t.isCompressed = (attrFlag & 0x08) != 0;
		t.isMipMap = (attrFlag & 0x10) != 0;
		t.isDoubleBuff = (attrFlag & 0x20) != 0;
		t.pixelType = Texb.PIXEL_TYPE[((attrFlag & 0x00C0) >> 6)];

		t.vertexLen = dis.readUnsignedShort();
		t.indexLen = dis.readUnsignedShort();
		t.imageCnt = dis.readUnsignedShort();
		t.image = new Timg[t.imageCnt];
		for (int i = 0; i < t.imageCnt; i++) {
			Timg img = new Timg();
			img.tag = readString(dis, 4);
			img.size = dis.readUnsignedShort();
			img.pathLen = dis.readUnsignedShort();
			img.path = readString(dis, img.pathLen).replaceAll("^I", "");
			int spFlag = dis.readUnsignedShort();
			if (spFlag != 0xffff) {
				logger.error("Image FFFF align error");
			}
			// System.out.println(spFlag == 0xffff);

			int imgTypeFlag = dis.readUnsignedShort();
			int[] flagArr = { dis.readUnsignedByte(), dis.readUnsignedByte(), dis.readInt() };
			if (flagArr[0] != 0 || flagArr[1] != 0 || flagArr[2] != 1) {
				logger.error("未知的Flag组：({},{},{})", flagArr[0], flagArr[1], flagArr[2]);
				continue;
			}
			if (imgTypeFlag >= 5) {
				imgTypeFlag = dis.readUnsignedByte();
				if (imgTypeFlag == 1) {
					logger.info("该图片是ScrollBar");
					dis.skipBytes(31);
				} else if (imgTypeFlag == 5) {
					throw new IOException("该图片是Scale9");
				} else {
					throw new IOException("该图片的KLB类型未知");
				}
			} else {
				dis.skipBytes(2);
			}
			img.vertexLen = dis.readUnsignedByte();
			img.indexLen = dis.readUnsignedByte();
			img.width = dis.readUnsignedShort();
			img.height = dis.readUnsignedShort();
			img.centerX = dis.readUnsignedShort();
			img.centerY = dis.readUnsignedShort();

			ArrayList<Vertice> vertices = new ArrayList<Vertice>(img.vertexLen);
			for (int j = 0; j < img.vertexLen; j++) {
				Vertice vertice = new Vertice();
				vertice.x = dis.readInt() / 0x10000;
				vertice.y = dis.readInt() / 0x10000;
				vertice.u = dis.readInt() * t.canvasWidth / 0x10000;
				vertice.v = dis.readInt() * t.canvasHeight / 0x10000;
				vertices.add(vertice);
			}
			Collections.sort(vertices, new Comparator<Vertice>() {
				public int compare(Vertice v1, Vertice v2) {
					return (int) ((v1.u + v1.v) - (v2.u + v2.v));
				}
			});
			img.vertices = vertices.toArray(new Vertice[img.vertexLen]);
			img.indices = new int[img.indexLen];
			for (int j = 0; j < img.indexLen; j++) {
				img.indices[j] = dis.readUnsignedByte();
			}
			t.image[i] = img;
		}

		int compressType = dis.readInt();

		byte[] bitmap = getBitmap(dis);
		if (t.isCompressed) {
			if (compressType != 0) {
				throw new IOException("未知的压缩格式");
			}
			bitmap = decompress(bitmap);
		}

		int[] pixelArr = new int[t.canvasWidth * t.canvasHeight];
		if (t.pixelType.equals("4444 RGBA")) {
			int ptr = 0;
			for (int i = 0; i < bitmap.length; i++) {
				if ((bitmap[i] & 0x0F) == 0x0F) {
					pixelArr[ptr] = (0xFF) << 24; // A
				} else {
					pixelArr[ptr] = (bitmap[i] & 0x0F) << 28; // A
				}
				pixelArr[ptr] += (bitmap[i + 1] & 0xF0) << 16; // R
				pixelArr[ptr] += (bitmap[i + 1] & 0x0F) << 12; // G
				pixelArr[ptr] += (bitmap[i] & 0xF0); // B
				i++;
				ptr++;
			}
		} else if (t.pixelType.equals("5551 RGBA")) {
			int ptr = 0;
			for (int i = 0; i < bitmap.length; i++) {
				if ((bitmap[i] & 0x01) == 1) {
					pixelArr[ptr] = (0xFF) << 28; // A
				} else {
					pixelArr[ptr] = (0x00) << 28; // A
				}
				pixelArr[ptr] += (bitmap[i + 1] & 0xF8) << 16; // R
				pixelArr[ptr] += (bitmap[i + 1] & 0x07) << 13; // G
				pixelArr[ptr] += (bitmap[i] & 0xC0) << 5; // G
				pixelArr[ptr] += (bitmap[i] & 0x3E) << 2; // B
				i++;
				ptr++;
			}
		} else if (t.pixelType.equals("565 RGB")) {
			int ptr = 0;
			for (int i = 0; i < bitmap.length; i++) {
				pixelArr[ptr] = (0xFF) << 28; // A
				pixelArr[ptr] += (bitmap[i + 1] & 0xF8) << 16; // R
				pixelArr[ptr] += (bitmap[i + 1] & 0x07) << 13; // G
				pixelArr[ptr] += (bitmap[i] & 0xE0) << 5; // G
				pixelArr[ptr] += (bitmap[i] & 0x1F) << 3; // B
				i++;
				ptr++;
			}
		} else if (t.pixelType.equals("Byte")) {
			int ptr = 0;
			for (int i = 0; i < bitmap.length; i++) {
				pixelArr[ptr] = (bitmap[i + 3] & 0xFF) << 24; // A
				pixelArr[ptr] += (bitmap[i] & 0xFF) << 16; // R
				pixelArr[ptr] += (bitmap[i + 1] & 0xFF) << 8; // G
				pixelArr[ptr] += (bitmap[i + 2] & 0xFF); // B
				i += 3;
				ptr++;
			}
		}
		dis.close();
		// 根据bitmap构造图片
		BufferedImage image = new BufferedImage(t.canvasWidth, t.canvasHeight,
				BufferedImage.TYPE_INT_ARGB);
		image.setRGB(0, 0, t.canvasWidth, t.canvasHeight, pixelArr, 0, t.canvasWidth);
		t.totalImage = image;
		return t;
		// 拆分图片并进行缓存

	}

	@Override
	public String getRefTextureFilePath(String path) throws IOException {
		if (path.endsWith(".imag")) {
			this.imagPath = new String(path.trim());
		} else {
			this.imagPath = path.trim() + ".imag";
		}
		String assetsPath = SIFConfig.getInstance().get(ConfigName.assetsPath);
		File root = new File(assetsPath).getParentFile();
		File imagFile = new File(imagPath);
		if (!imagFile.isAbsolute()) {
			imagFile = new File(root, imagPath);
		}

		Imag imag = new Imag();
		FileInputStream imagFile_;
		try{
			imagFile_ = new FileInputStream(imagFile);
		}catch(FileNotFoundException e){
			logger.info("Can't find image in external, searching in install...");
			root = new File(assetsPath.replace("external", "install")).getParentFile();
			imagFile = new File(root, imagPath);
			imagFile_ = new FileInputStream(imagFile);
		}
		DataInputStream dis = new DataInputStream(imagFile_);
		imag.tag = readString(dis, 4);
		imag.pathLen = dis.readInt();
		imag.texbPath = readString(dis, imag.pathLen).trim();
		dis.close();
		return imag.texbPath;
	}

	@Override
	public BufferedImage getImage(String path) throws IOException {
		// 检查Temp中有没有这个图片
		String checkerPath;
		if (path.endsWith(".imag")) {
			checkerPath = path.replaceAll("\\.imag.*$", "");
		} else {
			checkerPath = path;
		}
		File tempChecker = new File(tempDir, checkerPath);
		if (tempChecker.exists()) {
			BufferedImage image = ImageIO.read(tempChecker);
			return image;
		}

		// 如果Temp中没有这个图片，得到这个图片对应的Texb文件的path
		String texbPath = getRefTextureFilePath(path);
		// 解压这个texb文件, 到临时文件, 同时返回需要的图片
		Texb t = extractTexb(texbPath);
		return splitImage(t, t.totalImage);
	}

	public BufferedImage getImageWithoutSplit(String texbPath) throws IOException {
		String checkerPath;
		if (texbPath.endsWith(".texb")) {
			checkerPath = texbPath + ".png";
		} else {
			checkerPath = texbPath;
		}
		File tempChecker = new File(tempDir, checkerPath);
		if (tempChecker.exists()) {
			BufferedImage image = ImageIO.read(tempChecker);
			return image;
		}
		Texb t = extractTexb(texbPath);
		tempChecker.getParentFile().mkdirs();
		ImageIO.write(t.totalImage, "png", tempChecker);
		return t.totalImage;
	}

	private static class Vertice {
		int x, y, u, v;

		@Override
		public String toString() {
			return "Vertice [x=" + x + ", y=" + y + ", u=" + u + ", v=" + v + "]";
		}

	}

	private static class Timg {
		String tag;
		int size;
		int pathLen;
		String path;
		int vertexLen;
		int indexLen;
		int width;
		int height;
		int centerX;
		int centerY;
		Vertice[] vertices;
		int[] indices;

		@Override
		public String toString() {
			return "Timg [tag=" + tag + ", size=" + size + ", pathLen=" + pathLen + ", path="
					+ path + ", vertexLen=" + vertexLen + ", indexLen=" + indexLen + ", width="
					+ width + ", height=" + height + ", centerX=" + centerX + ", centerY="
					+ centerY + ", vertices=" + Arrays.toString(vertices) + ", indices="
					+ Arrays.toString(indices) + "]";
		}

	}

	private static class Texb {
		private static String[] IMG_TYPE = { "ALPHA", "LUMA", "LUMALPHA", "RGB", "RGBA" };
		private static String[] PIXEL_TYPE = { "565 RGB", "5551 RGBA", "4444 RGBA", "Byte" };
		String tag;
		int size;
		int pathLen;
		String path;
		int canvasWidth;
		int canvasHeight;
		String imgType;
		boolean isCompressed;
		boolean isMipMap;
		boolean isDoubleBuff;
		String pixelType;
		int vertexLen;
		int indexLen;
		int imageCnt;
		Timg[] image;
		BufferedImage totalImage;

		@Override
		public String toString() {
			return "Texb [tag=" + tag + ", size=" + size + ", pathLen=" + pathLen + ", path="
					+ path + ", canvasWidth=" + canvasWidth + ", canvadHeight=" + canvasHeight
					+ ", imgType=" + imgType + ", isCompressed=" + isCompressed + ", isMipMap="
					+ isMipMap + ", isDoubleBuff=" + isDoubleBuff + ", pixelType=" + pixelType
					+ ", vertexLen=" + vertexLen + ", indexLen=" + indexLen + ", imageCnt="
					+ imageCnt + "]";
		}

	}

	private static class Imag {
		String tag;
		int pathLen;
		String texbPath;

		@Override
		public String toString() {
			return "Imag [tag=" + tag + ", pathLen=" + pathLen + ", refPath=" + texbPath + "]";
		}
	}

	public static void main(String[] args) throws Exception {
		// BufferedImage image = new ImagDaoImpl()
		// .getImage("assets/image/background/b_liveback_001.png");
		// ImageIO.write(image, "png", new File("t.png"));
		SIFConfig.getInstance().loadConfig();
		List<String> l = new ImagDaoImpl().getImagList();
		for (String s : l) {
			System.out.println(s);
		}
	}

	@Override
	public List<String> getImagList() {
		List<String> l = new LinkedList<String>();
		String startPath = SIFConfig.getInstance().get(ConfigName.assetsPath);
		File startFile = new File(startPath);
		dfs(startFile, l, ".imag");
		return l;
	}

	@Override
	public List<String> getTexbList() {
		List<String> l = new LinkedList<String>();
		String startPath = SIFConfig.getInstance().get(ConfigName.assetsPath);
		File startFile = new File(startPath);
		dfs(startFile, l, ".texb");
		return l;
	}

	private void dfs(File f, List<String> l, String suffix) {
		if (f.isDirectory()) {
			File[] children = f.listFiles();
			if (children != null) {
				for (File child : children) {
					dfs(child, l, suffix);
				}
			}
		} else if (f.isFile()) {
			if (f.getName().endsWith(suffix)) {
				l.add(f.getAbsolutePath());
			}
		}
	}

}
 public class UnitDaoImpl implements UnitDao {
	private String dbPath;
	private Connection conn;

	public UnitDaoImpl() throws ClassNotFoundException, SQLException, FileNotFoundException {
		dbPath = SIFConfig.getInstance().get(ConfigName.dbPath);
		File cardDbFile = new File(new File(dbPath), "unit/unit.db_");
		if (!cardDbFile.exists()) {
			throw new FileNotFoundException(cardDbFile.getAbsolutePath() + " doesn't exist!");
		}
		dbPath = cardDbFile.getAbsolutePath();
		conn = SqlLiteConnection.getInstance().getConnection(dbPath);
	}

	@Override
	public List<Integer> getUnitIdList() throws SQLException {
		List<Integer> list = new ArrayList<Integer>();
		PreparedStatement preStatement = conn.prepareStatement("select unit_id from unit_m");
		ResultSet rs = preStatement.executeQuery();
		while (rs.next()) {
			Integer i = new Integer(rs.getInt("unit_id"));
			list.add(i);
		}
		return list;
	}

	@Override
	public List<Integer> getUnitNumList() throws SQLException {
		List<Integer> list = new ArrayList<Integer>();
		PreparedStatement preStatement = conn.prepareStatement("select unit_number from unit_m");
		ResultSet rs = preStatement.executeQuery();
		while (rs.next()) {
			Integer i = new Integer(rs.getInt("unit_number"));
			list.add(i);
		}
		return list;
	}

	@Override
	public UnitDTO getUnitById(int id) throws SQLException {
		PreparedStatement preStatement = conn
				.prepareStatement("select * from unit_m where unit_id=?");
		preStatement.setInt(1, id);
		ResultSet rs = preStatement.executeQuery();
		if (rs.next()) {
			UnitDTO dto = new UnitDTO();
			dto.setUnitId(rs.getInt("unit_id"));
			dto.setUnitNumber(rs.getInt("unit_number"));
			dto.setUnitTypeId(rs.getInt("unit_type_id"));
			dto.setEponym(rs.getString("eponym"));
			dto.setName(rs.getString("name"));
			dto.setNormalCardId(rs.getInt("normal_card_id"));
			dto.setIdolizeCardId(rs.getInt("rank_max_card_id"));
			dto.setMaxBondCardId(0);
			dto.setMaxLevelCardId(0);
			dto.setAllMaxCardId(rs.getInt("rank_max_card_id"));
			dto.setNormalAvatarPath(rs.getString("normal_icon_asset"));
			dto.setIdolizeAvatarPath(rs.getString("rank_max_icon_asset"));
			dto.setNormalCGAssetId(rs.getInt("normal_unit_navi_asset_id"));
			dto.setIdolizeCGAssetId(rs.getInt("rank_max_unit_navi_asset_id"));
			dto.setRarity(rs.getInt("rarity"));
			dto.setAttrId(rs.getInt("attribute_id"));
			dto.setDefaultSkillId(rs.getInt("default_unit_skill_id"));
			dto.setSkillAssetVoiceId(0);
			dto.setDefaultLeaderSkillId(rs.getInt("default_leader_skill_id"));
			dto.setMessage("");
			dto.setMaxNormalBond(rs.getInt("before_love_max"));
			dto.setMaxIdolizeBond(rs.getInt("after_love_max"));
			dto.setMaxNormalLevel(rs.getInt("before_level_max"));
			dto.setMaxIdolizeLevel(rs.getInt("after_level_max"));
			dto.setLevelUpPatternId(rs.getInt("unit_level_up_pattern_id"));
			dto.setMaxStamina(rs.getInt("hp_max"));
			dto.setMaxSmile(rs.getInt("smile_max"));
			dto.setMaxPure(rs.getInt("pure_max"));
			dto.setMaxCool(rs.getInt("cool_max"));
			dto.setIdolizeCost(rs.getInt("rank_up_cost"));
			return dto;
		}
		return null;
	}

	@Override
	public UnitDTO getUnitByNum(int num) throws SQLException {
		PreparedStatement preStatement = conn
				.prepareStatement("select * from unit_m where unit_number=?");
		preStatement.setInt(1, num);
		ResultSet rs = preStatement.executeQuery();
		if (rs.next()) {
			UnitDTO dto = new UnitDTO();
			dto.setUnitId(rs.getInt("unit_id"));
			dto.setUnitNumber(rs.getInt("unit_number"));
			dto.setUnitTypeId(rs.getInt("unit_type_id"));
			dto.setEponym(rs.getString("eponym"));
			dto.setName(rs.getString("name"));
			dto.setNormalCardId(rs.getInt("normal_card_id"));
			dto.setIdolizeCardId(rs.getInt("rank_max_card_id"));
			dto.setMaxBondCardId(0);
			dto.setMaxLevelCardId(0);
			dto.setAllMaxCardId(rs.getInt("rank_max_card_id"));
			dto.setNormalAvatarPath(rs.getString("normal_live_asset"));
			dto.setIdolizeAvatarPath(rs.getString("level_love_max_live_asset"));
			dto.setNormalCGAssetId(rs.getInt("normal_unit_navi_asset_id"));
			dto.setIdolizeCGAssetId(rs.getInt("rank_max_unit_navi_asset_id"));
			dto.setRarity(rs.getInt("rarity"));
			dto.setAttrId(rs.getInt("attribute_id"));
			dto.setDefaultSkillId(rs.getInt("default_unit_skill_id"));
			dto.setSkillAssetVoiceId(0);
			dto.setDefaultLeaderSkillId(rs.getInt("default_leader_skill_id"));
			dto.setMessage(rs.getString("unit_message"));
			dto.setMaxNormalBond(rs.getInt("before_love_max"));
			dto.setMaxIdolizeBond(rs.getInt("after_love_max"));
			dto.setMaxNormalLevel(rs.getInt("before_level_max"));
			dto.setMaxIdolizeLevel(rs.getInt("after_level_max"));
			dto.setLevelUpPatternId(rs.getInt("unit_level_up_pattern_id"));
			dto.setMaxStamina(rs.getInt("hp_max"));
			dto.setMaxSmile(rs.getInt("smile_max"));
			dto.setMaxPure(rs.getInt("pure_max"));
			dto.setMaxCool(rs.getInt("cool_max"));
			dto.setIdolizeCost(rs.getInt("rank_up_cost"));
			return dto;
		}
		return null;
	}

	@Override
	public List<UnitDTO> getAllUnits() throws SQLException {
		List<UnitDTO> list = new ArrayList<UnitDTO>();
		PreparedStatement preStatement = conn.prepareStatement("select * from unit_m where unit_number != 0");
		ResultSet rs = preStatement.executeQuery();
		while (rs.next()) {
			UnitDTO dto = new UnitDTO();
			dto.setUnitId(rs.getInt("unit_id"));
			dto.setUnitNumber(rs.getInt("unit_number"));
			dto.setUnitTypeId(rs.getInt("unit_type_id"));
			dto.setEponym(rs.getString("eponym"));
			dto.setName(rs.getString("name"));
			dto.setNormalCardId(rs.getInt("normal_card_id"));
			dto.setIdolizeCardId(rs.getInt("rank_max_card_id"));
			dto.setMaxBondCardId(0);
			dto.setMaxLevelCardId(0);
			dto.setAllMaxCardId(rs.getInt("rank_max_card_id"));
			dto.setNormalAvatarPath(rs.getString("normal_icon_asset"));
			dto.setIdolizeAvatarPath(rs.getString("rank_max_icon_asset"));
			dto.setNormalCGAssetId(rs.getInt("normal_unit_navi_asset_id"));
			dto.setIdolizeCGAssetId(rs.getInt("rank_max_unit_navi_asset_id"));
			dto.setRarity(rs.getInt("rarity"));
			dto.setAttrId(rs.getInt("attribute_id"));
			dto.setDefaultSkillId(rs.getInt("default_unit_skill_id"));
			dto.setSkillAssetVoiceId(0);
			dto.setDefaultLeaderSkillId(rs.getInt("default_leader_skill_id"));
			dto.setMessage("");
			dto.setMaxNormalBond(rs.getInt("before_love_max"));
			dto.setMaxIdolizeBond(rs.getInt("after_love_max"));
			dto.setMaxNormalLevel(rs.getInt("before_level_max"));
			dto.setMaxIdolizeLevel(rs.getInt("after_level_max"));
			//dto.setDefaultSkillCapacity(rs.getInt("default_removable_skill_capacity"));
			//dto.setMaxSkillCapacity(rs.getInt("max_removable_skill_capacity"));
			dto.setLevelUpPatternId(rs.getInt("unit_level_up_pattern_id"));
			dto.setMaxStamina(rs.getInt("hp_max"));
			dto.setMaxSmile(rs.getInt("smile_max"));
			dto.setMaxPure(rs.getInt("pure_max"));
			dto.setMaxCool(rs.getInt("cool_max"));
			dto.setIdolizeCost(rs.getInt("rank_up_cost"));
			list.add(dto);
		}
		return list;
	}

	@Override
	public String getAttrName(int attrId) throws SQLException {
		PreparedStatement preStatement = conn
				.prepareStatement("select name from unit_attribute_m where attribute_id=?");
		preStatement.setInt(1, attrId);
		ResultSet rs = preStatement.executeQuery();
		if (rs.next()) {
			return rs.getString("name");
		}
		return "Encrypted";
	}

	@Override
	public String getUnitNameImgPath(int type_id) throws SQLException {
		PreparedStatement preStatement = conn
				.prepareStatement("select name_image_asset from unit_type_m where unit_type_id = ?");
		preStatement.setInt(1, type_id);
		ResultSet rs = preStatement.executeQuery();
		if (rs.next()) {
			return rs.getString("name_image_asset");
		}
		return null;
	}

	@Override
	public String getRarityName(int rarityId) throws SQLException {
		String result = "";
		switch(rarityId){
		case 1:
			result = "N";break;
		case 2:
			result = "R";break;
		case 3:
			result = "SR";break;
		case 4:
			result = "UR";break;
		case 5:
			result = "SSR";break;
		}
		return result;
	}

	@Override
	public LeaderSkillDTO getLeaderSkill(int leaderSkillId) throws SQLException {
		PreparedStatement preStatement = conn
				.prepareStatement("select * from unit_leader_skill_m where unit_leader_skill_id=?");
		preStatement.setInt(1, leaderSkillId);
		ResultSet rs = preStatement.executeQuery();
		if (rs.next()) {
			LeaderSkillDTO dto = new LeaderSkillDTO();
			dto.setLeaderSkillId(rs.getInt("unit_leader_skill_id"));
			dto.setName(rs.getString("name"));
			dto.setDescription(rs.getString("description"));
			return dto;
		}
		return null;
	}

	@Override
	public SkillDTO getSkill(int skillId) throws SQLException {
		PreparedStatement preStatement = conn
				.prepareStatement("select * from unit_skill_m where unit_skill_id=?");
		preStatement.setInt(1, skillId);
		ResultSet rs = preStatement.executeQuery();
		if (rs.next()) {
			SkillDTO dto = new SkillDTO();
			dto.setSkillId(rs.getInt("unit_skill_id"));
			dto.setName(rs.getString("name"));
			dto.setSkillNameAsset(rs.getString("skill_name_asset"));
			dto.setMaxLevel(rs.getInt("max_level"));
			dto.setEffectType(rs.getInt("skill_effect_type"));
			dto.setDischargeType(rs.getInt("discharge_type"));
			dto.setTriggerType(rs.getInt("trigger_type"));
			return dto;
		}
		return null;
	}

	@Override
	public List<SkillLevelDetailDTO> getSkillLevelDetail(int skillId) throws SQLException {
		List<SkillLevelDetailDTO> list = new ArrayList<SkillLevelDetailDTO>();
		PreparedStatement preStatement = conn
				.prepareStatement("select * from unit_skill_level_m where unit_skill_id=?");
		preStatement.setInt(1, skillId);
		ResultSet rs = preStatement.executeQuery();
		while (rs.next()) {
			SkillLevelDetailDTO dto = new SkillLevelDetailDTO();
			dto.setSkillId(rs.getInt("unit_skill_id"));
			dto.setSkillLevel(rs.getInt("skill_level"));
			dto.setDescription(rs.getString("description"));
			dto.setEffectRange(rs.getInt("effect_range"));
			dto.setEffectValue(rs.getDouble("effect_value"));
			dto.setDischargeTime(rs.getDouble("discharge_time"));
			dto.setTriggerValue(rs.getInt("trigger_value"));
			dto.setActivationRate(rs.getInt("activation_rate"));
			list.add(dto);
		}
		return list;
	}

	@Override
	public String getSkillEffectTypeName(int skillEffectType) {
		switch (skillEffectType) {
		case 0:
			return "<Unavailable>";
		case 4:
			return "Discount+";
		case 5:
			return "Discount++";
		case 9:
			return "Life+";
		case 11:
			return "Score+";
		default:
			System.err.println("Unknown Effect ID: " + skillEffectType);
			return "<Unknown>";
		}
	}

	@Override
	public String getSkillTriggerTypeName(int triggerType) {
		switch (triggerType) {
		case 0:
			return "<Unavailable>";
		case 1:
			return "Time";
		case 3:
			return "Note";
		case 4:
			return "Combo";
		case 5:
			return "Score";
		case 6:
			return "Perfect";
		case 12:
			return "Star";
		default:
			System.err.println("Unknown Trigger ID: " + triggerType);
			return "<Unknown>";
		}
	}

	public static void main(String[] args) throws Exception {
		SIFConfig.getInstance().loadConfig();
		List<SkillLevelDetailDTO> l = new UnitDaoImpl().getSkillLevelDetail(1);
		for (SkillLevelDetailDTO dto : l) {
			System.out.println(dto);
		}
//		System.out.println(new UnitDaoImpl().getSkill(1));
//		System.out.println(new UnitDaoImpl().getRarityName(1));
	}

	@Override
	public String getUnitNaviAsset(int unitNaviAssetId) throws SQLException {
		PreparedStatement preStatement = conn
				.prepareStatement("select unit_navi_asset from unit_navi_asset_m where unit_navi_asset_id=?");
		preStatement.setInt(1, unitNaviAssetId);
		ResultSet rs = preStatement.executeQuery();
		if (rs.next()) {
			return rs.getString("unit_navi_asset");
		}
		return null;
	}

}
 public class CardBaseDTO {
	private int cardBaseId;
	private int layerOrder;
	private int cardLayerId;

	/**
	 * 获得卡片ID
	 * 
	 * @return
	 */
	public int getCardBaseId() {
		return cardBaseId;
	}

	/**
	 * 对应card_base_m表中的card_base_id
	 * 
	 * @param cardBaseId
	 */
	public void setCardBaseId(int cardBaseId) {
		this.cardBaseId = cardBaseId;
	}

	/**
	 * 获得所在的层次
	 * 
	 * @return
	 */
	public int getLayerOrder() {
		return layerOrder;
	}

	/**
	 * 对应card_base_m表中的layer_order
	 * 
	 * @param layerOrder
	 */
	public void setLayerOrder(int layerOrder) {
		this.layerOrder = layerOrder;
	}

	/**
	 * 获得对应的CardLayer的ID
	 * 
	 * @return
	 */
	public int getCardLayerId() {
		return cardLayerId;
	}

	/**
	 * 对应card_base_m表中的card_layer_id
	 * 
	 * @param cardLayerId
	 */
	public void setCardLayerId(int cardLayerId) {
		this.cardLayerId = cardLayerId;
	}

	@Override
	public String toString() {
		return "CardBaseDTO [cardBaseId=" + cardBaseId + ", layerOrder=" + layerOrder
				+ ", cardLayerId=" + cardLayerId + "]";
	}

}
 public class CardDTO {
	private static final Logger logger = LoggerFactory.getLogger(CardDTO.class);
	private int cardId;
	private int cardBaseId;
	private int unitNaviAssetId;
	private int naviLayerOrder;
	private int naviRotation;
	private int naviMoveX;
	private int naviMoveY;
	private double naviSizeRatio;
	private String flashAsset;

	public int getCardId() {
		return cardId;
	}

	public void setCardId(int cardId) {
		this.cardId = cardId;
	}

	public int getCardBaseId() {
		return cardBaseId;
	}

	public void setCardBaseId(int cardBaseId) {
		this.cardBaseId = cardBaseId;
	}

	public int getUnitNaviAssetId() {
		return unitNaviAssetId;
	}

	public void setUnitNaviAssetId(int unitNaviAssetId) {
		this.unitNaviAssetId = unitNaviAssetId;
	}

	public int getNaviLayerOrder() {
		return naviLayerOrder;
	}

	public void setNaviLayerOrder(int naviLayerOrder) {
		this.naviLayerOrder = naviLayerOrder;
	}

	public int getNaviRotation() {
		return naviRotation;
	}

	public void setNaviRotation(int naviRotation) {
		this.naviRotation = naviRotation;
	}

	public int getNaviMoveX() {
		return naviMoveX;
	}

	public void setNaviMoveX(int naviMoveX) {
		this.naviMoveX = naviMoveX;
	}

	public int getNaviMoveY() {
		return naviMoveY;
	}

	public void setNaviMoveY(int naviMoveY) {
		this.naviMoveY = naviMoveY;
	}

	public double getNaviSizeRatio() {
		return naviSizeRatio;
	}

	public void setNaviSizeRatio(double naviSizeRatio) {
		this.naviSizeRatio = naviSizeRatio;
	}

	public String getFlashAsset() {
		return flashAsset;
	}

	public void setFlashAsset(String flashAsset) {
		this.flashAsset = flashAsset;
	}

	@Override
	public String toString() {
		return "CardDTO [cardId=" + cardId + ", cardBaseId=" + cardBaseId + ", unitNaviAssetId="
				+ unitNaviAssetId + ", naviLayerOrder=" + naviLayerOrder + ", naviRotation="
				+ naviRotation + ", naviMoveX=" + naviMoveX + ", naviMoveY=" + naviMoveY
				+ ", naviSizeRatio=" + naviSizeRatio + ", flashAsset=" + flashAsset + "]";
	}

}
 public class UnitDTO {
	private int unitId;
	private int unitNumber;
	private int unitTypeId;
	private String eponym;
	private String name;
	private int normalCardId;
	private int idolizeCardId;
	private int maxLevelCardId;
	private int maxBondCardId;
	private int allMaxCardId;
	private String normalAvatarPath;
	private String idolizeAvatarPath;
	private int normalCGAssetId;
	private int idolizeCGAssetId;
	private int rarity;
	private int attrId;
	private int defaultSkillId;
	private int skillAssetVoiceId;
	private int defaultLeaderSkillId;
	private String message;
	private int maxNormalBond;
	private int maxIdolizeBond;
	private int maxNormalLevel;
	private int maxIdolizeLevel;
	private int levelUpPatternId;
	private int maxStamina;
	private int maxSmile;
	private int maxPure;
	private int maxCool;
	private int idolizeCost;

	public int getUnitId() {
		return unitId;
	}

	public void setUnitId(int unitId) {
		this.unitId = unitId;
	}

	public int getUnitNumber() {
		return unitNumber;
	}

	public void setUnitNumber(int unitNumber) {
		this.unitNumber = unitNumber;
	}

	public int getUnitTypeId() {
		return unitTypeId;
	}

	public void setUnitTypeId(int unitTypeId) {
		this.unitTypeId = unitTypeId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getNormalCardId() {
		return normalCardId;
	}

	public void setNormalCardId(int normalCardId) {
		this.normalCardId = normalCardId;
	}

	public int getIdolizeCardId() {
		return idolizeCardId;
	}

	public void setIdolizeCardId(int idolizeCardId) {
		this.idolizeCardId = idolizeCardId;
	}

	public int getMaxLevelCardId() {
		return maxLevelCardId;
	}

	public void setMaxLevelCardId(int maxLevelCardId) {
		this.maxLevelCardId = maxLevelCardId;
	}

	public int getMaxBondCardId() {
		return maxBondCardId;
	}

	public void setMaxBondCardId(int maxBondCardId) {
		this.maxBondCardId = maxBondCardId;
	}

	public int getAllMaxCardId() {
		return allMaxCardId;
	}

	public void setAllMaxCardId(int allMaxCardId) {
		this.allMaxCardId = allMaxCardId;
	}

	public String getNormalAvatarPath() {
		return normalAvatarPath;
	}

	public void setNormalAvatarPath(String normalAvatarPath) {
		this.normalAvatarPath = normalAvatarPath;
	}

	public String getIdolizeAvatarPath() {
		return idolizeAvatarPath;
	}

	public void setIdolizeAvatarPath(String idolizeAvatarPath) {
		this.idolizeAvatarPath = idolizeAvatarPath;
	}

	public int getNormalCGAssetId() {
		return normalCGAssetId;
	}

	public void setNormalCGAssetId(int normalCGAssetId) {
		this.normalCGAssetId = normalCGAssetId;
	}

	public int getIdolizeCGAssetId() {
		return idolizeCGAssetId;
	}

	public void setIdolizeCGAssetId(int idolizeCGAssetId) {
		this.idolizeCGAssetId = idolizeCGAssetId;
	}

	public int getRarity() {
		return rarity;
	}

	public void setRarity(int rarity) {
		this.rarity = rarity;
	}

	public int getDefaultSkillId() {
		return defaultSkillId;
	}

	public void setDefaultSkillId(int defaultSkillId) {
		this.defaultSkillId = defaultSkillId;
	}

	public int getSkillAssetVoiceId() {
		return skillAssetVoiceId;
	}

	public void setSkillAssetVoiceId(int skillAssetVoiceId) {
		this.skillAssetVoiceId = skillAssetVoiceId;
	}

	public int getDefaultLeaderSkillId() {
		return defaultLeaderSkillId;
	}

	public void setDefaultLeaderSkillId(int defaultLeaderSkillId) {
		this.defaultLeaderSkillId = defaultLeaderSkillId;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public int getMaxNormalLevel() {
		return maxNormalLevel;
	}

	public void setMaxNormalLevel(int maxNormalLevel) {
		this.maxNormalLevel = maxNormalLevel;
	}

	public int getMaxIdolizeLevel() {
		return maxIdolizeLevel;
	}

	public void setMaxIdolizeLevel(int maxIdolizeLevel) {
		this.maxIdolizeLevel = maxIdolizeLevel;
	}

	public int getLevelUpPatternId() {
		return levelUpPatternId;
	}

	public void setLevelUpPatternId(int levelUpPatternId) {
		this.levelUpPatternId = levelUpPatternId;
	}

	public int getMaxStamina() {
		return maxStamina;
	}

	public void setMaxStamina(int maxStamina) {
		this.maxStamina = maxStamina;
	}

	public int getMaxSmile() {
		return maxSmile;
	}

	public void setMaxSmile(int maxSmile) {
		this.maxSmile = maxSmile;
	}

	public int getMaxPure() {
		return maxPure;
	}

	public void setMaxPure(int maxPure) {
		this.maxPure = maxPure;
	}

	public int getMaxCool() {
		return maxCool;
	}

	public void setMaxCool(int maxCool) {
		this.maxCool = maxCool;
	}

	public int getIdolizeCost() {
		return idolizeCost;
	}

	public void setIdolizeCost(int idolizeCost) {
		this.idolizeCost = idolizeCost;
	}

	public int getAttrId() {
		return attrId;
	}

	public void setAttrId(int attrId) {
		this.attrId = attrId;
	}

	public int getMaxNormalBond() {
		return maxNormalBond;
	}

	public void setMaxNormalBond(int maxNormalBond) {
		this.maxNormalBond = maxNormalBond;
	}

	public int getMaxIdolizeBond() {
		return maxIdolizeBond;
	}

	public void setMaxIdolizeBond(int maxIdolizeBond) {
		this.maxIdolizeBond = maxIdolizeBond;
	}

	public String getEponym() {
		return eponym;
	}

	public void setEponym(String eponym) {
		this.eponym = eponym;
	}

	@Override
	public String toString() {
		return "UnitDTO [unitId=" + unitId + ", unitNumber=" + unitNumber + ", unitTypeId="
				+ unitTypeId + ", eponym=" + eponym + ", name=" + name + ", normalCardId="
				+ normalCardId + ", idolizeCardId=" + idolizeCardId + ", maxLevelCardId="
				+ maxLevelCardId + ", maxBondCardId=" + maxBondCardId + ", allMaxCardId="
				+ allMaxCardId + ", normalAvatarPath=" + normalAvatarPath + ", idolizeAvatarPath="
				+ idolizeAvatarPath + ", normalCGAssetId=" + normalCGAssetId
				+ ", idolizeCGAssetId=" + idolizeCGAssetId + ", rarity=" + rarity + ", attrId="
				+ attrId + ", defaultSkillId=" + defaultSkillId + ", skillAssetVoiceId="
				+ skillAssetVoiceId + ", defaultLeaderSkillId=" + defaultLeaderSkillId
				+ ", message=" + message + ", maxNormalBond=" + maxNormalBond + ", maxIdolizeBond="
				+ maxIdolizeBond + ", maxNormalLevel=" + maxNormalLevel + ", maxIdolizeLevel="
				+ maxIdolizeLevel + ", levelUpPatternId=" + levelUpPatternId + ", maxStamina="
				+ maxStamina + ", maxSmile=" + maxSmile + ", maxPure=" + maxPure + ", maxCool="
				+ maxCool + ", idolizeCost=" + idolizeCost + "]";
	}

}
 public class CardImage {
	public static enum LayerStatus {
		ON, OFF, DISABLED
	}

	private LayerStatus[] layerStatus = new LayerStatus[9];
	private BufferedImage image;
	private String imagePath;

	public CardImage() {
		for (int i = 0; i < 9; i++) {
			layerStatus[i] = LayerStatus.DISABLED;
		}
	}

	public LayerStatus[] getLayerStatus() {
		return layerStatus;
	}

	public BufferedImage getImage() {
		return image;
	}

	public void setImage(BufferedImage image) {
		this.image = image;
	}

	public void setLayerStatus(int index, LayerStatus status) {
		layerStatus[index] = status;
	}

	public String getImagePath() {
		return imagePath;
	}

	public void setImagePath(String imagePath) {
		this.imagePath = imagePath;
	}

}
 public static enum LayerStatus {
	ON, OFF, DISABLED
}
 public class ImageUtil {
	public static BufferedImage resize(BufferedImage img, double percent) {
		int w = (int) (img.getWidth() * percent);
		int h = (int) (img.getHeight() * percent);
		BufferedImage scaledImage = Scalr.resize(img, Method.QUALITY, w, h);
		return scaledImage;
	}

	public static BufferedImage move(BufferedImage img, int offsetX, int offsetY) {
		int w = img.getWidth() + offsetX;
		int h = img.getHeight() + offsetY;
		BufferedImage newImg = new BufferedImage(w, h,
				BufferedImage.TYPE_INT_ARGB);
		Graphics g = newImg.getGraphics();
		g.drawImage(img, offsetX > 0 ? offsetX : 0, offsetY > 0 ? offsetY : 0,
				w, h, offsetX > 0 ? 0 : (-offsetX), offsetY > 0 ? 0
						: (-offsetY), img.getWidth(), img.getHeight(), null);
		g.dispose();
		return newImg;
	}

	public static BufferedImage merge(ArrayList<BufferedImage> list) {
		// create the new image, canvas size is the max. of both image sizes
		int w = list.get(0).getWidth();
		int h = list.get(0).getHeight();
		BufferedImage combined = new BufferedImage(w, h,
				BufferedImage.TYPE_INT_ARGB);

		// paint both images, preserving the alpha channels
		Graphics g = combined.getGraphics();
		for (BufferedImage img : list) {
			g.drawImage(img,0,0,w,h,0,0,w,h,null);
		}
		g.dispose();
		return combined;
	}
}

import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import me.xwang1024.sifResExplorer.data.CardDao;
import me.xwang1024.sifResExplorer.data.ImagDao;
import me.xwang1024.sifResExplorer.data.UnitDao;
import me.xwang1024.sifResExplorer.data.impl.CardDaoImpl;
import me.xwang1024.sifResExplorer.data.impl.ImagDaoImpl;
import me.xwang1024.sifResExplorer.data.impl.UnitDaoImpl;
import me.xwang1024.sifResExplorer.dto.CardBaseDTO;
import me.xwang1024.sifResExplorer.dto.CardDTO;
import me.xwang1024.sifResExplorer.dto.UnitDTO;
import me.xwang1024.sifResExplorer.model.CardImage;
import me.xwang1024.sifResExplorer.model.CardImage.LayerStatus;
import me.xwang1024.sifResExplorer.util.ImageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

			rarity_prefix = "R";break;
		case 3:
			rarity_prefix = "SR";break;
		case 4:
			rarity_prefix = "UR";break;
		case 5:
			rarity_prefix = "SSR";break;
		}
		switch(attribute){
		case 1:
			attribute_prefix = "1";break;
		case 2:
			attribute_prefix = "2";break;
		case 3:
			attribute_prefix = "3";break;
		case 5:
			attribute_prefix = "9";break;
		}
		if(rarity >= 3){
			attribute_prefix = "4";
		}
		result = "assets/image/cards/frame/f_" + rarity_prefix + "_" + attribute_prefix + ".png.imag";
		return result;
	}

	private String getLvName(int attribute, boolean is_lv_max){
		String result = "";
		String attribute_prefix = "";
		String lv_prefix = "";
		switch(attribute){
		case 1:
			attribute_prefix = "smile";break;
		case 2:
			attribute_prefix = "pure";break;
		case 3:
			attribute_prefix = "cool";break;
		}

		if(is_lv_max){
			lv_prefix = "on";
		}else{
			lv_prefix = "off";
		}

		result = "assets/image/cards/lv/v_" + attribute_prefix + "_" + lv_prefix + ".png.imag";
		return result;
	}

	private String getBondName(int attribute, boolean is_bound_max){
		String result = "";
		String attribute_prefix = "";
		String lv_prefix = "";
		switch(attribute){
		case 1:
			attribute_prefix = "smile";break;
		case 2:
			attribute_prefix = "pure";break;
		case 3:
			attribute_prefix = "cool";break;
		}

		if(is_bound_max){
			lv_prefix = "on";
		}else{
			lv_prefix = "off";
		}

		result = "assets/image/cards/love/o_" + attribute_prefix + "_" + lv_prefix + ".png.imag";
		return result;
	}

	private String getRarityName(int rarity, int attribute){
		String result = "";
		String rarity_prefix = "";
		String attribute_prefix = "";
		switch(rarity){
		case 1:
			rarity_prefix = "N";break;
		case 2:
			rarity_prefix = "R";break;
		case 3:
			rarity_prefix = "SR";break;
		case 4:
			rarity_prefix = "UR";break;
		case 5:
			rarity_prefix = "SSR";break;
		}
		switch(attribute){
		case 1:
			attribute_prefix = "smile";break;
		case 2:
			attribute_prefix = "pure";break;
		case 3:
			attribute_prefix = "cool";break;
		case 5:
			attribute_prefix = "all";break;
		}
		result = "assets/image/cards/rarity/r_" + attribute_prefix + "_" + rarity_prefix + ".png.imag";
		return result;
	}

	private String getStarName(int rarity, boolean idolized){
		String result = "";
		int star_count = 0;
		switch(rarity){
		case 1:star_count = 1;break;
		case 2:star_count = 3;break;
		case 3:star_count = 5;break;
		case 4:star_count = 9;break;
		case 5:star_count = 7;break;
		}
		if(idolized)
			star_count += 1;
		String star_count_ = String.valueOf(star_count);
		if(star_count < 10)
			star_count_ = "0" + star_count_;
		result = "assets/image/cards/star/s_0" + star_count_ + ".png.imag";
		return result;
	}


	private CardImage getCard(int cardId, boolean[] layerFlag, int id, int idolized) throws SQLException, IOException {
