/*  OpenOlap viewer
 *  パッケージ名：openolap.viewer.dao
 *  ファイル：PostgresDimensionDAO.java
 *  説明：
 *
 *  作成日: 2004/01/06
 */
package openolap.viewer.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;

import openolap.viewer.AxisLevel;
import openolap.viewer.Dimension;
import openolap.viewer.Report;
import openolap.viewer.common.Messages;
import openolap.viewer.common.CommonSettings;
import openolap.viewer.common.StringUtil;
import openolap.viewer.controller.RequestHelper;

/**
 *  クラス：PostgresDimensionDAO
 *  説明：
 */
public class PostgresDimensionDAO implements DimensionDAO {

	Connection conn = null;

	// ********** コンストラクタ **********

	PostgresDimensionDAO(Connection conn) {
		this.conn = conn;
	}



	// ********** メソッド **********

	// @param DimSeq：DimensionSeq
	// @param partSeq：partSeq
	// @return：DBの物理テーブル名を返す
	public String getDimensionTableName(String dimSeq, String partSeq) throws IllegalArgumentException {
		if ((dimSeq == null) || (partSeq == null) ) { throw new IllegalArgumentException();}
		if ((dimSeq == "") || (partSeq == "") ) { throw new IllegalArgumentException();}

		return "oo_dim_" + dimSeq + "_" + partSeq;
	}

	public ArrayList selectDimensions(String cubeSeq) throws SQLException {

		ArrayList dimensionList = new ArrayList();
		Dimension dim = null;
		String SQL = "";
		Statement stmt = null;
		ResultSet rs = null;

		String timeDimDispName = Messages.getString("PostgresDimensionDAO.timeDimDispName"); //$NON-NLS-1$
		SQL =   "";
		SQL +=	" select ";
		SQL +=	"    distinct coalesce(d.name,'" + timeDimDispName + "') as name, ";
		SQL +=	"    c.time_dim_flg, ";
		SQL +=	"    d.total_flg, ";
		SQL +=	"    c.DIMENSION_SEQ, ";
		SQL +=	"    CASE WHEN c.PART_SEQ=0 THEN 1 ";
		SQL +=	"         ELSE c.PART_SEQ ";
		SQL +=	"    END, ";
		SQL +=	"    coalesce(d.COMMENT,'') as COMMENT, ";
		SQL +=	"    c.DIM_NO ";
		SQL +=	" from ";
		SQL +=	"    oo_info_dim c left outer join ";
		SQL +=  "    (select dimension_seq,name,total_flg,comment from oo_dimension union select time_seq,name,total_flg,comment from oo_time) d ";
		SQL +=  "    on (c.dimension_seq=d.dimension_seq) ";
		SQL +=	" where c.cube_seq=" + cubeSeq;
		SQL +=	" order by DIM_NO";
//System.out.println("selectDimensions SQL:" + SQL);

		try {
			stmt = conn.createStatement();
			rs = stmt.executeQuery(SQL);

			int i=0;
			while ( rs.next() ) {

				// 時間次元かどうか、合計値を持つかを設定
				boolean timeDimFLG = false; // 時間次元かどうか
				boolean hasTotalFLG = false;// 合計値を持つか
				if ( rs.getString("time_dim_flg").equals("1") ) {		// 時間ディメンション
					if ( i != 0 ){ throw new IllegalStateException();} //(時間次元は必ず一番最初になる)
					timeDimFLG = true;
					hasTotalFLG = hasTimeDimhaveTotal(cubeSeq, rs.getString("DIMENSION_SEQ"));
				} else {												// 時間ディメンション以外のディメンション

					if ( rs.getString("total_flg").equals("1") ) {		// 合計値を持つ
//System.out.println("has Total");
						hasTotalFLG = true;	
					}
				}

				dim = new Dimension(Integer.toString(i+1),							// ID
										rs.getString("name"), 						// name
										rs.getString("COMMENT"), 					// comment
										new ArrayList(), 							// axisLevelList 
										null, 										// defaultMemberKey
										false, 									// isMeasure
										false, 									// isUsedSelecter
										timeDimFLG, 								// isTimeDim
										hasTotalFLG, 								// hasTotal
										rs.getString("DIMENSION_SEQ"), 				// Dimension seq
										rs.getString("PART_SEQ"));					// part seq

//System.out.println(rs.getString("name") + "," + rs.getString("time_dim_flg") + "," + rs.getString("COMMENT"));
//System.out.println(timeDimFLG + "," + hasTotalFLG);
//System.out.println(rs.getString("DIMENSION_SEQ") + "," + rs.getString("PART_SEQ"));

				// Dimension オブジェクトに AxisLevel オブジェクトを追加
				DAOFactory daoFactory = DAOFactory.getDAOFactory();
				AxisLevelDAO axisLevelDAO = daoFactory.getAxisLevelDAO(this.conn);		
				Iterator it = axisLevelDAO.selectAxisLevels(cubeSeq,dim).iterator();
				while (it.hasNext()) {
					AxisLevel axisLevel = (AxisLevel) it.next();
					dim.addAxisLevelList(axisLevel);
				}

				dimensionList.add(dim);
				i++;
			}
		} catch (SQLException e) {
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null){
					rs.close();
				}
			} catch (SQLException e) {
				throw e;
			} finally {
				try {
					if (stmt != null){
						stmt.close();
					}
				} catch (SQLException e) {
					throw e;
				}
			}
		}

		return dimensionList;
	}

	// ディメンションのメンバー名の表示タイプ情報を更新
	public void registDimensionMemberDispType(RequestHelper helper, CommonSettings commonSettings) {
		
		HttpServletRequest request = helper.getRequest();
		String dimMemDispTypes = (String)request.getParameter("dimMemDispTypes");		
		Report report = (Report)helper.getRequest().getSession().getAttribute("report");

		ArrayList dimIDDispTypePairList = StringUtil.splitString(dimMemDispTypes,",");
		Iterator it = dimIDDispTypePairList.iterator();
		while (it.hasNext()) {
			String dimIDDispTypePair = (String) it.next();
			ArrayList dimIDDispTypeList = StringUtil.splitString(dimIDDispTypePair,":");

			String dimID =(String)dimIDDispTypeList.get(0);				// 軸ID
			String dispMemberType = (String) dimIDDispTypeList.get(1);	// メンバー表示名称タイプ

			if( (!Dimension.DISP_LONG_NAME.equals(dispMemberType)) && 		// 取得した値が正しい値かどうかを確認
			     (!Dimension.DISP_SHORT_NAME.equals(dispMemberType) )) {
				throw new IllegalArgumentException();
			}

			Dimension dim = (Dimension) report.getAxisByID(dimID);
			dim.setDispMemberNameType(dispMemberType);

		}

	}

	// ********** privateメソッド **********

	private boolean hasTimeDimhaveTotal(String cubeSeq, String dimensionSeq) throws SQLException {
		boolean isTimeDim   = false;
		boolean hasTotalFLG = false;

		Statement stmt = null;
		ResultSet rs = null;
		String SQL = "";
		SQL =   "";
		SQL +=	"select ";
		SQL +=	"  distinct total_flg ";
		SQL +=	"from ";
		SQL +=	"  oo_time ";
		SQL +=	"where ";
		SQL +=	"  time_seq=" + dimensionSeq;
// System.out.println("SQL:" + SQL);
		try {
			stmt = conn.createStatement();
			rs = stmt.executeQuery(SQL);
			while ( rs.next() ) {

				// 合計値を持つか
				if ( rs.getString("total_flg") != null ) {
					if ( rs.getString("total_flg").equals("1") ) {
						hasTotalFLG = true;
					}
				}
			}
		} catch (SQLException e) {
			throw e;
		} finally {
			try {
				if (rs != null){
					rs.close();
				}
			} catch (SQLException e) {
				throw e;
			} finally {
				try {
					if (stmt != null){
						stmt.close();
					}
				} catch (SQLException e) {
					throw e;
				}
			}
		}

		return hasTotalFLG;
	}

}
