/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2008 Aimluck,Inc.
 * http://aipostyle.com/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.aimluck.eip.modules.screens;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.resources.JetspeedResources;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.turbine.util.RunData;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.context.Context;

import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipUser;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.common.ALPermissionException;
import com.aimluck.eip.exttimecard.ExtTimecardResultDataNew;
import com.aimluck.eip.exttimecard.ExtTimecardSelectData;
import com.aimluck.eip.exttimecard.ExtTimecardExcelCreate;
import com.aimluck.eip.exttimecard.util.ExtTimecardUtils;
import com.aimluck.eip.orm.DatabaseOrmService;
import com.aimluck.eip.services.accessctl.ALAccessControlConstants;
import com.aimluck.eip.util.ALEipUtils;

/**
 * タイムカードのファイル出力を取り扱うクラスです
 */
public class ExtTimecardXlsExportScreen extends ALXlsScreen {
  /** logger */
  private static final JetspeedLogger logger = JetspeedLogFactoryService
      .getLogger(ExtTimecardXlsExportScreen.class.getName());

  public static final String FILE_NAME = "timecard.xls";

  /** ログインユーザーID */
  private String userid;

  /** ログインユーザー名 */
  private String username;

  /** 一時フォルダへのフォルダ */
  private File rootFolder;

  private String view_month;

  /** アクセス権限の機能名 */
  private String aclPortletFeature = null;

  /* add 2010/08/23 wangzhiyu Start--- */
  
  /** 負荷プロファイル */
  private final String FILEPATH_PROPERTIES = JetspeedResources.getString(
      "aipo.conf", "")
      + "/MaothReport.properties";

  /* add 2010/08/23 wangzhiyu End--- */
  
  /* add 2010/08/23 wangzhiyu Start--- */
  
  /** 記事を読むの設定ファイル */
  
  private String getDailyBatchDocumentProperty(String key) {
    try {
      Properties prop = new Properties();

      // ファイルが存在しない場合はnullを返す。
      File file = new File(FILEPATH_PROPERTIES);
      if (!file.exists()) {
        return null;
      }

      prop.load(new FileInputStream(FILEPATH_PROPERTIES));
      String value = prop.getProperty(key);

      return value;
    } catch (Exception e) {
      logger.error("DailyBatchDocumentDaemon", e);
      return null;
    }
	
    /* add 2010/08/23 wangzhiyu End--- */
  }

  /**
   * 初期化処理を行います。
   * 
   * @param action
   * @param rundata
   * @param context
   */
  public void init(RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {

    String target_user_id = rundata.getParameters().getString(
        ExtTimecardUtils.TARGET_USER_ID);
    userid = Integer.toString(ALEipUtils.getUserId(rundata));

    rootFolder = ExtTimecardUtils.getRootFolder(DatabaseOrmService
        .getInstance().getOrgId(rundata), ALEipUtils.getUserId(rundata));

    view_month = rundata.getParameters().getString("view_month");

    // アクセス権
    if (target_user_id == null || "".equals(target_user_id)
        || userid.equals(target_user_id)) {
      aclPortletFeature = ALAccessControlConstants.POERTLET_FEATURE_TIMECARD_TIMECARD_SELF;
    } else {
      aclPortletFeature = ALAccessControlConstants.POERTLET_FEATURE_TIMECARD_TIMECARD_OTHER;
    }

    super.init(rundata, context);
  }

  /* add 2010/08/23 wangzhiyu Start--- */
  // 親クラスのこのメソッドは
  protected boolean createXLSFile(RunData rundata, Context context,
      String filepath) {
    try {

      String templateFilepath = rundata.getServletContext().getRealPath(
          "/ExcelTemplate");
      String tempfile = getDailyBatchDocumentProperty("templatePath");
      FileInputStream excelFile = new FileInputStream(templateFilepath + "/"
          + tempfile);
      POIFSFileSystem fs = new POIFSFileSystem(excelFile);
      // 負荷がテンプレート
      HSSFWorkbook wb = new HSSFWorkbook(fs);
      createHSSFWorkbook(rundata, context, wb);
      File file = new File(filepath);
      if (file.exists()) {
        file.delete();
      }

      FileOutputStream output = new FileOutputStream(file);
      
      wb.write(output);
      output.flush();
      output.close();
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
    return true;
  }
  
  /* add 2010/08/23 wangzhiyu End--- */
  protected boolean createHSSFWorkbook(RunData rundata, Context context,
      HSSFWorkbook wb) {
    try {
      setupTimecardSheet(rundata, context, wb);
    } catch (Exception e) {
      logger.error("TimecardCsvExportScreen", e);
      return false;
    }
    return true;
  }

  private void setupTimecardSheet(RunData rundata, Context context,
      HSSFWorkbook wb) throws Exception {

    ExtTimecardSelectData listData = new ExtTimecardSelectData();
    listData.initField();
    listData.setRowsNum(1000);
    listData.doViewList(this, rundata, context);
    
    ExtTimecardResultDataNew rdn = listData.getTimecardResultData();
    ExtTimecardExcelCreate.execute(rdn, wb);
    
   
    /* Delete 2010/08/18 wangchao Start--- */
    /*
     * String sheet_name = "タイムカード"; // ヘッダ部作成 String[] headers = { "氏名", "日付",
     * "曜日", "勤務形態", "出勤時間", "退勤時間", "出勤日数", "就業時間", "残業日数", "残業時間", "休出日数",
     * "休出時間", "遅刻日数", "早退日数", "欠勤日数", "有休日数", "代休日数", "その他日数", "修正理由、備考",
     * "外出１", "復帰１", "外出２", "復帰２", "外出３", "復帰３", "外出４", "復帰４", "外出５", "復帰５" }; //
     * 0：日本語，1：英数字 short[] cell_enc_types = { HSSFCell.ENCODING_UTF_16,
     * HSSFCell.ENCODING_UTF_16, HSSFCell.ENCODING_UTF_16,
     * HSSFCell.ENCODING_UTF_16, HSSFCell.ENCODING_UTF_16,
     * HSSFCell.ENCODING_UTF_16, HSSFCell.CELL_TYPE_NUMERIC,日
     * HSSFCell.CELL_TYPE_NUMERIC, HSSFCell.CELL_TYPE_NUMERIC,
     * HSSFCell.CELL_TYPE_NUMERIC, HSSFCell.CELL_TYPE_NUMERIC,
     * HSSFCell.CELL_TYPE_NUMERIC, HSSFCell.CELL_TYPE_NUMERIC,
     * HSSFCell.CELL_TYPE_NUMERIC, HSSFCell.CELL_TYPE_NUMERIC,
     * HSSFCell.CELL_TYPE_NUMERIC, HSSFCell.CELL_TYPE_NUMERIC,
     * HSSFCell.CELL_TYPE_NUMERIC, HSSFCell.ENCODING_UTF_16,
     * HSSFCell.ENCODING_UTF_16, HSSFCell.ENCODING_UTF_16,
     * HSSFCell.ENCODING_UTF_16, HSSFCell.ENCODING_UTF_16,
     * HSSFCell.ENCODING_UTF_16, HSSFCell.ENCODING_UTF_16,
     * HSSFCell.ENCODING_UTF_16, HSSFCell.ENCODING_UTF_16,
     * HSSFCell.ENCODING_UTF_16, HSSFCell.ENCODING_UTF_16 }; HSSFSheet sheet =
     * createHSSFSheet(wb, sheet_name, headers, cell_enc_types);
     * 
     * int rowcount = 0; // スタイルの設定 HSSFCellStyle style_col =
     * wb.createCellStyle();
     * style_col.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
     * style_col.setAlignment(HSSFCellStyle.ALIGN_JUSTIFY);
     * 
     * String user_name = ALEipUtils.getUserFullName(Integer.parseInt(listData
     * .getTargetUserId()));// 氏名 String system_name =
     * ExtTimecardUtils.getEipTExtTimecardSystemByUserId(
     * Integer.parseInt(listData.getTargetUserId())).getSystemName();
     * 
     * ExtTimecardListResultData tclistrd = null;
     * 
     * List daykeys = listData.getDateListKeys(); int daykeysize =
     * daykeys.size(); for (int i = 0; i < daykeysize; i++) { tclistrd =
     * (ExtTimecardListResultData) daykeys.get(i);
     * 
     * List viewlist = tclistrd.getViewList(); int viewlistsize =
     * viewlist.size();
     * 
     * String date = "";// 日付 String day = ""; // 曜日 String service_form =
     * system_name; // 勤務形態 String clock_in_time = "";// 出勤時間 String
     * clock_out_time = "";// 退勤時間 String work_day = "0"; // 出勤日数 0 or 1 String
     * work_hour = "0";// 就業時間 String overtime_day = "0";// 残業日数 String
     * overtime_hour = "0";// 残業時間 String off_day = "0";// 休出日数 String off_hour =
     * "0";// 休出時間 String late_coming_day = "0";// 遅刻日数 String early_leaving_day =
     * "0";// 早退日数 String absent_day = "0";// 欠勤日数 String paid_holiday = "0";//
     * 有休日数 String compensatory_holiday = "0";// 代休日数 String other_day = "0";//
     * その他日数 String remark = "";// 修正理由、備考 String[] out_going = new
     * String[EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY];// 外出 String[]
     * come_back = new String[EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY];// 復帰
     * List list = new ArrayList();
     * 
     * if (tclistrd.getRd() == null) { // ExtTimecardResultData rd =
     * tclistrd.getRd();
     * 
     * date = tclistrd.getDateStr("yyyy/MM/dd"); day =
     * tclistrd.getDateStr("EE"); } else {
     * 
     * ExtTimecardResultData rd = tclistrd.getRd(); //
     * ExtTimecardSummaryResultData srd = tclistrd.get
     * 
     * date = tclistrd.getDateStr("yyyy/MM/dd"); day =
     * tclistrd.getDateStr("EE"); String type = rd.getType().toString(); if
     * (type.equals(EipTExtTimecard.TYPE_WORK)) { clock_in_time =
     * rd.getClockInTime("HH:mm"); clock_out_time = rd.getClockOutTime("HH:mm");
     * if (tclistrd.getInworkHour() > 0.0) { work_day = "1"; work_hour =
     * Float.toString(tclistrd.getWorkHourWithoutRestHour()); } else { work_hour =
     * "0"; } if (tclistrd.getOutworkHour() > 0.0) { overtime_day = "1";
     * overtime_hour = Float.toString(tclistrd
     * .getOvertimeHourWithoutRestHour()); } else { overtime_hour = "0"; } if
     * (tclistrd.getOffWorkHour() > 0.0) { off_day = "1"; off_hour =
     * Float.toString(tclistrd.getOffWorkHour()); } else { off_hour = "0"; } }
     * if (rd.getRefixFlag().getValue() == "1") { remark = (String)
     * rd.getReason().getValue(); } late_coming_day = tclistrd.isLateComing() ?
     * "1" : "0"; early_leaving_day = tclistrd.isEarlyLeaving() ? "1" : "0";
     * absent_day = type.equals(EipTExtTimecard.TYPE_ABSENT) ? "1" : "0";
     * paid_holiday = type.equals(EipTExtTimecard.TYPE_HOLIDAY) ? "1" : "0";
     * compensatory_holiday = type.equals(EipTExtTimecard.TYPE_COMPENSATORY) ?
     * "1" : "0"; other_day = type.equals(EipTExtTimecard.TYPE_ETC) ? "1" : "0";
     * 
     * list = tclistrd.getOutgoingComeback_xls(); for (int j = 0; j <
     * EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY; j++) { Map map = (HashMap)
     * list.get(j); out_going[j] = (String) map.get("outgoing"); come_back[j] =
     * (String) map.get("comeback"); } }
     * 
     * String[] rows = { user_name, date, day, service_form, clock_in_time,
     * clock_out_time, work_day, work_hour, overtime_day, overtime_hour,
     * off_day, off_hour, late_coming_day, early_leaving_day, absent_day,
     * paid_holiday, compensatory_holiday, other_day, remark, out_going[0],
     * come_back[0], out_going[1], come_back[1], out_going[2], come_back[2],
     * out_going[3], come_back[3], out_going[4], come_back[4] }; rowcount =
     * rowcount + 1; addRow(sheet.createRow(rowcount), cell_enc_types, rows); } /*
     * rowcount = rowcount + 1; String NOTHING = null; String work_day =
     * "=SUM(G2:G" + rowcount + ")"; String work_hour = "=SUM(H2:H" + rowcount +
     * ")"; String overtime_day = "=SUM(I2:I" + rowcount + ")"; String
     * overtime_hour = "=SUM(J2:J" + rowcount + ")"; String off_day =
     * "=SUM(K2:K" + rowcount + ")"; String off_hour = "=SUM(L2:L" + rowcount +
     * ")"; String late_coming_day = "=SUM(M2:M" + rowcount + ")"; String
     * early_leaving_day = "=SUM(N2:N" + rowcount + ")"; String absent_day =
     * "=SUM(O2:O" + rowcount + ")"; String paid_holiday = "=SUM(P2:P" +
     * rowcount + ")"; String compensatory_holiday = "=SUM(Q2:Q" + rowcount +
     * ")"; String other_day = "=SUM(R2:R" + rowcount + ")"; String[] rows = {
     * NOTHING, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING, work_day,
     * work_hour, overtime_day, overtime_hour, off_day, off_hour,
     * late_coming_day, early_leaving_day, absent_day, paid_holiday,
     * compensatory_holiday, other_day, };
     * 
     * addFooter(sheet.createRow(rowcount), cell_enc_types, rows);
     */

    /*
     * int uid = ALEipUtils.getUserId(rundata);
     * ALEventlogFactoryService.getInstance().getEventlogHandler().logXlsScreen(
     * uid, "タイムカード出力", ALEventlogConstants.PORTLET_TYPE_TIMECARD_XLS_SCREEN);
     */
    /* Delete 2010/08/18 wangchao End--- */

  }

  protected String getFolderPath() {
    return rootFolder.getAbsolutePath();
  }

  protected String getFileName() {
    return FILE_NAME;
  }

  /**
   * アクセス権限チェック用メソッド。<br />
   * アクセス権限の機能名を返します。
   *
   * @return
   */
  public String getAclPortletFeature() {
    return aclPortletFeature;
  }

  
  
  // Add 2010/8/26 一覧表示と同じロジックに変更　(青柳
  
  /**
   * ダウンロードをやめて、作成ファイルを直接ストリーム出力するようにしたもの
   * 
   */
  protected void doOutput(RunData rundata) throws Exception {
    VelocityContext context = new VelocityContext();
    ServletOutputStream out = null;

    try {
      init(rundata, context);

      doCheckAclPermission(rundata, context, getDefineAclType());

      String templateFilepath = rundata.getServletContext().getRealPath("/ExcelTemplate");
      String tempfile = getDailyBatchDocumentProperty("templatePath");
      FileInputStream excelFile = new FileInputStream(templateFilepath + "/"
            + tempfile);
      POIFSFileSystem fs = new POIFSFileSystem(excelFile);
      HSSFWorkbook wb = new HSSFWorkbook(fs);
      
      /*
       * テンプレート用に新規EXCELファイルを作成する場合に上記と入れ替えて利用します
       * 
      HSSFWorkbook wb = new HSSFWorkbook();
      HSSFSheet sheet = wb.createSheet();
      */
      
      
      ExtTimecardSelectData listData = new ExtTimecardSelectData();
      listData.initField();
      listData.setRowsNum(1000);
      listData.doViewList(this, rundata, context);
      
      listData.setJobInfo(); // Add 2010/8/27 (青柳)
      
      /*
       * 
      HSSFRow r = sheet.createRow((short)1);
      HSSFCell c = r.createCell((short)1);
      c.setEncoding(HSSFCell.ENCODING_UTF_16);
      c.setCellValue("このファイルを整形してテンプレートを作成してください。");
      */
      
      ExtTimecardExcelCreate.executeVmLike(rundata, context, listData, wb);

      HttpServletResponse response = rundata.getResponse();
      /*
      byte[] encData;
      encData = "月報".getBytes("utf-8");
      String fileName = new String(encData, "ISO8859_1");
      encData = getUserNameByList(listData.getUsers(), listData.getTargetUserId()).getBytes("utf-8");
      String parsonName = new String(encData, "ISO8859_1");
      encData = String.format("%1$TY年%1$tm月", listData.getViewMonth().getValue()).getBytes("utf-8");
      String monthName = new String(encData, "ISO8859_1");
*/
      String fileName_full = URLEncoder.encode(
            String.format("%1$TY%1$tm", listData.getViewMonth().getValue()) + "_MonthlyReport_" + 
            getUserNameByList(listData.getUsers(), listData.getTargetUserId()) + ".xls", 
            "utf-8"); 
      response.setHeader("Content-disposition", "attachment; filename=\""
          + fileName_full + "\"");
      response.setContentType("application/msexcel");
   
      /** Update 2010/11/02 金廣 Start--- */
      // 課題53: ダウンロードした月報を保存せずに開きたいが、開けない問題の対応
      // IE6.0のバグ　http://support.microsoft.com/kb/436605/ja
      // 対応のため、no-cacheを使用しない。
      //response.setHeader("Cache-Control", "no-cache");
      //response.setHeader("Pragma", "no-cache");
      response.setHeader("Cache-Control", "private");
      response.setHeader("Pragma", "private");
      response.setHeader("Expires", "-1");
      /** Update 2010/11/02 金廣 End----- */

      // ファイル内容を直接ストリームへ出力
      out = response.getOutputStream();
      wb.write(out);
      
      out.flush();
      
    } catch (ALPermissionException e) {
      ALEipUtils.redirectPermissionError(rundata);
    } catch (Exception e) {
      logger.error("[ERROR]", e);
    }
  }
  
  /**
   * ユーザーリスト内の指定IDユーザーの名前を取得します。
   * 
   * TODO:TimecardUtilへ移動
   * 
   * @param ls
   * @param id
   * @return
   */
  private static String getUserNameByList(List<ALEipUser> ls, String id){
    for(Iterator<ALEipUser> itr = ls.iterator(); itr.hasNext();){
      ALEipUser u = itr.next();
      if(u.getUserId().getValueAsString().equals(id))
        return u.getName().getValue();
    }

    return "";
  }
  
  // Add 2010/8/26 一覧表示と同じロジックに変更   青柳) End
}
