/*
 * 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.cabinet.util;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.SelectQuery;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.resources.JetspeedResources;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.eip.cabinet.FolderInfo;
import com.aimluck.eip.cayenne.om.portlet.EipTCabinetFile;
import com.aimluck.eip.cayenne.om.portlet.EipTCabinetFolder;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.orm.DatabaseOrmService;
import com.aimluck.eip.util.ALEipUtils;

/**
 * キャビネットのユーティリティクラスです。 <BR>
 * 
 */
public class CabinetUtils {

  /** logger */
  private static final JetspeedLogger logger = JetspeedLogFactoryService
      .getLogger(CabinetUtils.class.getName());

  /** フォルダ『ルートフォルダ』の予約 ID */
  public static final int ROOT_FODLER_ID = 1;

  /** セッションの識別子 */
  public static final String KEY_FOLDER_ID = "folder_id";

  /** 共有ファイルを保管するディレクトリの指定 */
  private static final String FOLDER_FILEDIR_CABINET = JetspeedResources
      .getString("aipo.filedir", "");

  /**
   * フォルダオブジェクトモデルを取得します。 <BR>
   * 
   * @param rundata
   * @param context
   * @return
   */
  public static EipTCabinetFolder getEipTCabinetFolder(RunData rundata,
      Context context) {
    String folderid = ALEipUtils.getTemp(rundata, context, KEY_FOLDER_ID);

    try {
      if (folderid == null || Integer.valueOf(folderid) == null) {
        // ファイル IDが空の場合
        logger.debug("[Cabinet Folder] Empty ID...");
        return null;

      }

      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      SelectQuery query = new SelectQuery(EipTCabinetFolder.class);
      Expression exp = ExpressionFactory.matchDbExp(
          EipTCabinetFolder.FOLDER_ID_PK_COLUMN, folderid);
      query.setQualifier(exp);
      List folders = dataContext.performQuery(query);
      if (folders == null || folders.size() == 0) {
        // 指定したフォルダ IDのレコードが見つからない場合
        logger.debug("[Cabinet Folder] Not found ID...");
        return null;
      }
      return ((EipTCabinetFolder) folders.get(0));
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return null;
    }
  }

  /**
   * ファイルオブジェクトモデルを取得します。 <BR>
   * 
   * @param rundata
   * @param context
   * @return
   */
  public static EipTCabinetFile getEipTCabinetFile(RunData rundata,
      Context context) {
    String fileid = ALEipUtils.getTemp(rundata, context,
        ALEipConstants.ENTITY_ID);
    try {
      if (fileid == null || Integer.valueOf(fileid) == null) {
        // ファイル IDが空の場合
        logger.debug("[Cabinet File] Empty ID...");
        return null;
      }

      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      SelectQuery query = new SelectQuery(EipTCabinetFile.class);
      Expression exp = ExpressionFactory.matchDbExp(
          EipTCabinetFile.FILE_ID_PK_COLUMN, fileid);
      query.setQualifier(exp);
      List files = dataContext.performQuery(query);
      if (files == null || files.size() == 0) {
        // 指定したファイル IDのレコードが見つからない場合
        logger.debug("[Cabinet File] Not found ID...");
        return null;
      }

      return ((EipTCabinetFile) files.get(0));
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return null;
    }
  }

  /**
   * ファイルオブジェクトモデルを取得します。 <BR>
   * 
   * @param rundata
   * @param context
   * @return
   */
  public static List getEipTCabinetFileList(int folderId) {
    try {
      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      SelectQuery query = new SelectQuery(EipTCabinetFile.class);
      Expression exp = ExpressionFactory.matchExp(
          EipTCabinetFile.FOLDER_ID_PROPERTY, Integer.valueOf(folderId));
      query.setQualifier(exp);
      List files = dataContext.performQuery(query);
      if (files == null || files.size() == 0) {
        return null;
      }

      return files;
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return null;
    }
  }

  public static ArrayList getFolderList() {
    try {
      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      SelectQuery query = new SelectQuery(EipTCabinetFolder.class);
      List list = dataContext.performQuery(query);
      if (list == null || list.size() < 0)
        return null;

      ArrayList prerootlist = getEipTCabinetFolderList(list, 0, 0);

      ArrayList result = getFolderList(prerootlist);

      return result;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  public static ArrayList getFolderList(List list) {
    try {
      if (list == null || list.size() <= 0)
        return null;

      ArrayList res = new ArrayList();
      int size = list.size();
      for (int i = 0; i < size; i++) {
        FolderInfo info = (FolderInfo) list.get(i);
        res.add(info);
        List infos = info.getList();
        List a = getFolderList(infos);
        if (a != null && a.size() > 0) {
          res.addAll(a);
        }
      }
      return res;
    } catch (Exception e) {
      return null;
    }

  }

  private static ArrayList getEipTCabinetFolderList(List dblist, int parent_id,
      int hierarchy_index) {
    ArrayList list = new ArrayList();
    int size = dblist.size();
    for (int i = 0; i < size; i++) {
      EipTCabinetFolder folder = (EipTCabinetFolder) dblist.get(i);
      if (folder.getParentId().intValue() == parent_id) {
        FolderInfo info = new FolderInfo();
        info.setHierarchyIndex(hierarchy_index);
        info.setFolderId(folder.getFolderId().intValue());
        info.setParentFolderId(folder.getParentId().intValue());
        info.setFolderName(folder.getFolderName());
        list.add(info);
      }
    }

    if (list.size() <= 0)
      return null;

    int size2 = list.size();
    for (int i = 0; i < size2; i++) {
      FolderInfo info = (FolderInfo) list.get(i);
      List colist = getEipTCabinetFolderList(dblist, info.getFolderId(), info
          .getHierarchyIndex() + 1);
      if (colist != null && colist.size() > 0) {
        info.setList(colist);
      }
    }
    return list;
  }

  public static void setFolderVisible(ArrayList folder_list,
      FolderInfo selectedinfo) {
    if (folder_list == null || folder_list.size() <= 0)
      return;

    ArrayList list = new ArrayList();
    FolderInfo info = null;
    int hierarchy_index = 0;
    int parent_id = 0;
    int size = folder_list.size() - 1;
    for (int i = size; i >= 0; i--) {
      if (hierarchy_index < 0) {
        break;
      }
      info = (FolderInfo) folder_list.get(i);
      if (info.getFolderId() == selectedinfo.getFolderId()) {
        info.setOpened(true);
        list.add(0, info);
        parent_id = info.getParentFolderId();
        hierarchy_index = info.getHierarchyIndex() - 1;
      } else if (info.getFolderId() == parent_id) {
        // 親フォルダを捜す
        info.setOpened(true);
        list.add(0, info);
        parent_id = info.getParentFolderId();
        hierarchy_index = info.getHierarchyIndex() - 1;
      }
    }

    size = folder_list.size();
    for (int i = 0; i < size; i++) {
      FolderInfo info1 = (FolderInfo) folder_list.get(i);
      boolean containsId = false;
      for (int j = 0; j < list.size(); j++) {
        FolderInfo info2 = (FolderInfo) list.get(j);
        if (info1.getFolderId() == info2.getFolderId()) {
          containsId = true;
          break;
        } else if (info1.getParentFolderId() == info2.getFolderId()) {
          containsId = true;
          break;
        }
      }
      if (containsId) {
        info1.setVisible(true);
      } else {
        info1.setVisible(false);
      }
    }
  }

  public static String getFolderPosition(ArrayList folder_list, int folder_id) {
    String sepa = "<b> &gt; </b>";
    StringBuffer folderpath = new StringBuffer();
    FolderInfo info = null;
    int parent_id = -1;
    int size = folder_list.size() - 1;
    for (int i = size; i >= 0; i--) {
      info = (FolderInfo) folder_list.get(i);
      if (info.getFolderId() <= 1) {
        // 「ルートフォルダ」は含めない
        folderpath.insert(0, info.getFolderName());
        break;
      }
      if (info.getFolderId() == folder_id) {
        folderpath.append(sepa);
        folderpath.append(info.getFolderName());
        parent_id = info.getParentFolderId();
      } else if (info.getFolderId() == parent_id) {
        // 親フォルダを捜す
        folderpath.insert(0, info.getFolderName());
        folderpath.insert(0, sepa);
        parent_id = info.getParentFolderId();
      }
    }

    return folderpath.toString();
  }

  public static FolderInfo getSelectedFolderInfo(ArrayList list, int folder_id) {
    FolderInfo selected_folderinfo = null;
    int size = list.size();
    for (int i = 0; i < size; i++) {
      FolderInfo info = (FolderInfo) list.get(i);
      if (info.getFolderId() == folder_id) {
        selected_folderinfo = info;
        break;
      }
    }
    return selected_folderinfo;
  }

  /**
   * ユーザ毎のルート保存先（絶対パス）を取得します。
   * 
   * @param uid
   * @return
   */
  public static String getSaveDirPath(String orgId) {
    return FOLDER_FILEDIR_CABINET + File.separator + orgId + File.separator
        + "cabinet";
  }

  /**
   * ユーザ毎の保存先（相対パス）を取得します。
   * 
   * @param uid
   * @return
   */
  public static String getRelativePath(String fileName) {
    return new StringBuffer().append("/").append(fileName).toString();
  }

  /**
   * 添付ファイル保存先（絶対パス）を取得します。
   * 
   * @param uid
   * @return
   */
  public static String getAbsolutePath(String orgId, String fileName) {
    StringBuffer sb = new StringBuffer().append(FOLDER_FILEDIR_CABINET).append(
        File.separator).append(orgId).append(File.separator).append("cabinet");

    File f = new File(sb.toString());
    if (!f.exists()) {
      f.mkdirs();
    }

    return sb.append(File.separator).append(fileName).toString();
  }
}
