/**
 * Copyright (c) 2003-2004 System Integrator Corporation.
 *                 All Rights Reserved.
 */
package jp.co.sint.tools;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import jp.co.sint.basic.SILogin;
import jp.co.sint.basic.SIUserInfo;
import jp.co.sint.config.SIConfig;

import org.apache.log4j.Category;
import org.apache.regexp.RE;

/**
 * @version $Id: SIHTMLUtil.java,v 1.0 2003/07/25 Exp $
 * @author  Jinwang Chen
 * <br>Description: HTMLスクリプトと関連するユーティリティー
 * <p>History</p>
 * <p>Author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reason</p>
 * ============&nbsp;&nbsp;&nbsp;==========&nbsp;&nbsp;===========================<br>
 * J.W.Chen       2003/07/25  Original
 */

public class SIHTMLUtil {

  //ログ用のインスタンスの生成
  private static Category log=Category.getInstance(SIConfig.SILOG4J_WEBSHOP_CATEGORY_NAME);

  /**
   * <b>SIHTMLUtil</b>
   * コンストラクタ
   * @param なし
   * @return なし
   * @throws なし
   */
  public SIHTMLUtil() {}

  /**
   * <b>outputOneZero</b>
   * フラグの値によって、別の文字または、符号に変換して、出力します。
   * @param lOneZero フラグの値
   * @return フラグの値を代表する符号、または、文字
   * @throws なし
   */
  public static String outputOneZero(int lOneZero){
    return outputOneZero(String.valueOf(lOneZero),"O","&nbsp;");
  }

//7.2.1 ST2003 追加 ここから
  /**
   * <b>outputOneZero</b>
   * フラグの値によって、別の文字または、符号に変換して、出力します。
   * @param lOneZero フラグの値
   * @param defaultStr フラグの値が "NULL""0""1"のいずれでもなかったときのデフォルト
   * @return フラグの値を代表する符号、または、文字
   * @throws なし
   */
  public static String outputOneZero(int lOneZero, String defaultStr) {
    return outputOneZero(String.valueOf(lOneZero),"O","&nbsp;", defaultStr);
  }
//7.2.1 ST2003 追加 ここまで

  /**
   * <b>outputOneZero</b>
   * フラグの値によって、別の文字または、符号に変換して、出力します。
   * @param lOneZero フラグの値
   * @return フラグの値を代表する符号、または、文字
   * @throws なし
   */
  public static String outputOneZero(String lOneZero){
    return outputOneZero(lOneZero,"O","");
  }

//7.2.1 ST2003 追加 ここから
  /**
   * <b>outputOneZero</b>
   * フラグの値によって、別の文字または、符号に変換して、出力します。
   * @param lOneZero フラグの値
   * @param defaultStr フラグの値が "NULL""0""1"のいずれでもなかったときのデフォルト
   * @return フラグの値を代表する符号、または、文字
   * @throws なし
   */
  public static String outputOneZero(String lOneZero, String defaultStr){
    return outputOneZero(lOneZero,"O","", defaultStr);
  }
//7.2.1 ST2003 追加 ここまで

  /**
   * <b>outputOneZero</b>
   * フラグの値によって、別の文字または、符号に変換して、出力します。
   * @param lOneZero フラグの値
   * @param lOneScript フラグの値が、”1”の場合には、出力するスクリプト
   * @param lOneScript フラグの値が、”0”またnullの場合には、出力するスクリプト
   * @return フラグの値を代表する符号、または、文字
   * @throws なし
   */
  public static String outputOneZero(String lOneZero,String lOneScript,String lZeroScript){
//7.2.1 ST2003 追加 ここから
    return outputOneZero(lOneZero, lOneScript, lZeroScript, "0");
  }
  /**
   * <b>outputOneZero</b>
   * フラグの値によって、別の文字または、符号に変換して、出力します。
   * @param lOneZero フラグの値
   * @param lOneScript フラグの値が、”1”の場合には、出力するスクリプト
   * @param lOneScript フラグの値が、”0”またnullの場合には、出力するスクリプト
   * @param defaultStr フラグの値が "NULL""0""1"のいずれでもなかったときのデフォルト
   * @return フラグの値を代表する符号、または、文字
   * @throws なし
   */
  public static String outputOneZero(String lOneZero, String lOneScript, String lZeroScript, String defaultStr) {
    //7.2.1 ST2003 追加 ここまで
    if (SIUtil.isNull(lOneScript)) lOneScript="&nbsp;";
    else lOneScript=SIHTMLUtil.HTMLEncode(lOneScript);
    
    if (SIUtil.isNull(lZeroScript)) lZeroScript="&nbsp;";
    else lZeroScript=SIHTMLUtil.HTMLEncode(lZeroScript);
    
    if (SIUtil.isNull(lOneZero)) return lZeroScript;
    //7.2.1 ST2003 修正 ここから
    else if (lOneZero.trim().equalsIgnoreCase("0")) return lZeroScript;
    else if (lOneZero.trim().equalsIgnoreCase("1")) return lOneScript;
    else if (SIUtil.isNotNull(defaultStr) && defaultStr.trim().equalsIgnoreCase("1")) return lOneScript;
    else return lZeroScript;
    //else if (lOneZero.trim().equalsIgnoreCase("1")) return lOneScript;
    //else return lZeroScript;
    //7.2.1 ST2003 修正 ここまで
  }
  
  public static String amountFlgOneZero(String lOneZero){
    String lZeroScript ="&nbsp;";
    String lOneScript = SIHTMLUtil.HTMLEncode("◯");
    if (SIUtil.isNull(lOneZero)) return lZeroScript;
    else if (lOneZero.trim().equalsIgnoreCase("0")) return lZeroScript;
    else if (lOneZero.trim().equalsIgnoreCase("1")) return lOneScript;
    else return lZeroScript;
  }

  /**
   * <b>SJISEncode</b>
   * ページの画面に表示する文字をshift_jisのコードの文字に変更して、
   * HTMLスクリプトのフォーマットに沿って、変更します。
   * @param src 変換の対象の文字
   * @return 変換後の文字列
   * @throws なし
   */
  public static String SJISEncode(String src){
    if (src==null) return null;
    return HTMLEncode(SIUtil.changeToJIS(src));
  }
  
  //7.4.0 ST2083 追加 ここから
  /**
   * <b>JSHTMLEncode</b>
   * JavaScriptに応じてHTMLタグスクリプトをencodeする
   * @param src 元の文字列
   * @return 置換後の文字列
   * @throws なし
   */
  public static String JSHTMLEncode(String src){
    String lDest = SIStringUtil.replace(src,"\\","\\\\");
    lDest = SIStringUtil.replace(lDest,"'","\\'");
    return HTMLEncode(lDest);
  }
  //7.4.0 ST2083 追加 ここまで
  /**
   * <b>HTMLEncode</b>
   * HTMLタグスクリプトをencodeする
   * @param src 元の文字列
   * @return 置換後の文字列
   * @throws なし
   */
  public static String HTMLEncode(String src){
    if (src==null) return "";
    String lSpcWord="&#37211;";
    
    StringBuffer destBuf = new StringBuffer();
    src=SIUtil.CP932ToJIS(src);
    int len = src.length();
    
    for(int ii = 0; ii<len;ii++){
      char c = src.charAt(ii);
      switch(c){
        case '<': destBuf.append("&lt;"); break;
        case '>': destBuf.append("&gt;"); break;
        case '&': {
          if (len<(ii+lSpcWord.length())){
            destBuf.append("&amp;");
          }else if (src.substring(ii,ii+lSpcWord.length()).equals(lSpcWord)){
            destBuf.append(lSpcWord);
            ii=ii+lSpcWord.length()-1;
          }else{
            destBuf.append("&amp;");
          }
          break;
        }
        case '"': destBuf.append("&quot;"); break;
        default:destBuf.append(c); break;
      }
    }
    return destBuf.toString();
  }
  
  /**
   * <b>URLEncode</b>
   * URLの文字列をencodeする
   * @param src 元の文字列
   * @return 置換後の文字列
   * @throws なし
   */
  public static String URLEncode(HttpServletResponse response,String src){
    return response.encodeURL(src);
  }
  
  /**
   * <b>getPath</b>
   * トップパスを取得します。
   * @param request クライアントからのリクエスト
   * @return トップパス
   * @throws なし
   */
  public static String getRootPath(HttpServletRequest request){
    String contextPath = request.getContextPath();
    return contextPath;
  }
  
  public static String getPagePath(HttpServletRequest request){
    String pagePath = "other";
    String servletPath = request.getServletPath();
    if ("/main.jsp".equals(servletPath)) pagePath = "home";
    else if ("/hair_top.jsp".equals(servletPath)) pagePath = "hair";
    else if ("/commodity/cmdty_hair.jsp".equals(servletPath)) pagePath = "hair";
    else if ("/haircosme_top.jsp".equals(servletPath)) pagePath = "haircosme";
    else if ("/commodity/cmdty_haircosme.jsp".equals(servletPath)) pagePath = "haircosme";
    else if ("/esthe_top.jsp".equals(servletPath)) pagePath = "esthe";
    else if ("/commodity/cmdty_esthe.jsp".equals(servletPath)) pagePath = "esthe";
    else if ("/bed_top.jsp".equals(servletPath)) pagePath = "bed";
    else if ("/commodity/cmdty_bed.jsp".equals(servletPath)) pagePath = "bed";
    else if ("/cosme_top.jsp".equals(servletPath)) pagePath = "cosme";
    else if ("/commodity/cmdty_cosme.jsp".equals(servletPath)) pagePath = "cosme";
    else if ("/nail_top.jsp".equals(servletPath)) pagePath = "nail";
    else if ("/commodity/cmdty_nail.jsp".equals(servletPath)) pagePath = "nail";
    else if ("/book_top.jsp".equals(servletPath)) pagePath = "book";
    else if ("/commodity/cmdty_book.jsp".equals(servletPath)) pagePath = "book";
    else if ("/eyelash_top.jsp".equals(servletPath)) pagePath = "eyelash";
    else if ("/commodity/cmdty_eyelash.jsp".equals(servletPath)) pagePath = "eyelash";
    else if ("/used_top.jsp".equals(servletPath)) pagePath = "used";
    
    return pagePath;
  }
  
  /**
   * <b>getCmdtyImageRoot</b>
   * トップパスを取得します。
   * @param request クライアントからのリクエスト
   * @return トップパス
   * @throws なし
   */
  public static String getUploadFolder(HttpServletRequest request,int lIndex){
    String lPath=SIConfig.SIUPLOAD_FOLDER[lIndex];
    if (!lPath.startsWith("/"))lPath="/"+lPath;
    if (lPath.endsWith("/"))lPath=lPath.substring(0,lPath.length()-1);
    
    String contextPath = request.getContextPath();
    return contextPath+lPath;
  }
  
  /**
   * <b>initRequestSession</b>
   * 初めてある画面に対して表示するときに、古いセッションの情報を消すこと必要があります
   * @param request クライアントからのリクエスト
   * @param lSessionName  この画面に使用するセッション名
   * @return なし
   * @throws なし
   */
  public static void initRequest(HttpServletRequest lRequest,String lSessionName){
    if(SIStringUtil.null2Space((String)lRequest.getAttribute("remodify")).equals(SIConfig.SIACTION_REMODIFY)){
      return;
    }
    String lActionNameTxt=lRequest.getParameter("actionNameTxt");
    HttpSession lSession=null;
    if (SIUtil.isNull(lActionNameTxt) ||
        SIConfig.SIACTION_NEW.equalsIgnoreCase(lActionNameTxt)||
        SIConfig.SIACTION_MODIFY.equalsIgnoreCase(lActionNameTxt)||
        SIConfig.SIACTION_RESET.equalsIgnoreCase(lActionNameTxt)){
      lSession=lRequest.getSession(true);
      lSession.removeAttribute(lSessionName);
    }
  }
  
  /**
   * <b>getHTMLSpace</b>
   * HTMLのスペースを取得します。
   * @param lSpaceNum スペースの数
   * @return 指定した数のスペース
   * @throws なし
   */
  public static String getHTMLSpace(int lSpaceNum){
    StringBuffer lResultBuf=new StringBuffer();
    for (int ii=0;ii<lSpaceNum;ii++)lResultBuf.append("&nbsp;");
    return lResultBuf.toString();
  }
  
  /**
   * <b>SILogin</b>
   * 管理画面に管理者の情報を取得します。
   * @param lRequest リクエスト
   * @return 管理者のログイン情報
   * @throws なし
   */
  public static SILogin getLogin(HttpServletRequest lRequest){
    SILogin lLogin=(SILogin)lRequest.getSession().getAttribute(SIConfig.SISESSION_MAN_LOGIN_NAME);
    if (lLogin==null)return new SILogin();
    else return lLogin;
  }
  
  /**
   * <b>getUserInfo</b>
   * フロント側にユーザーのログイン情報を取得します。
   * @param lRequest リクエスト
   * @return ユーザーのログイン情報
   * @throws なし
   */
  public static SIUserInfo getUserInfo(HttpServletRequest lRequest){
    SIUserInfo lUserInfo=(SIUserInfo)lRequest.getSession().getAttribute(SIConfig.SISESSION_USERINFO_NAME);
    if (lUserInfo==null)return new SIUserInfo();
    else return lUserInfo;
  }
  
  public static void forward(HttpServletRequest request, HttpServletResponse response,String lForwardUrl)throws ServletException, IOException{
    RequestDispatcher rd =request.getRequestDispatcher(lForwardUrl);
    rd.forward(request, response);
  }
  
  public static void forwardKey(HttpServletRequest request, HttpServletResponse response,String lForwardKey)throws ServletException, IOException{
    String lUrl=SIURLMap.getUrl(lForwardKey);
    if (lUrl.trim().startsWith("/")) forward(request,response,lUrl.trim());
    else forward(request,response,"/"+lUrl.trim());
  }
  public static String ToHTMLNewLine(String lSrc){
    if (SIUtil.isNull(lSrc)) return "";
    String lRes=SIHTMLUtil.HTMLEncode(lSrc);
    lRes=SIStringUtil.replace(lRes,"\r\n","<BR>");
    lRes=SIStringUtil.replace(lRes,"\r","<BR>");
    return lRes;
  }
  public static String ToHTMLNewLine2(String lSrc){
    if (SIUtil.isNull(lSrc)) return "";
    lSrc=SIStringUtil.replace(lSrc,"\r\n","<BR>");
    lSrc=SIStringUtil.replace(lSrc,"\r","<BR>");
    lSrc=lSrc.replaceAll("<eg-only>.*</eg-only>","");
    lSrc=lSrc.replaceAll("<bg-only>","");
    lSrc=lSrc.replaceAll("</bg-only>","");
    return lSrc;
  }
  
  public static String URLEncode(String lUrl){
    if (SIUtil.isNull(lUrl)) return "";
    try {
      return URLEncoder.encode(lUrl,SIConfig.SIENCODE_SHIFT_JIS);
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
      return "";
    }
  }
  
  /**
  * <b>consHttps</b>
  * httpsのURLの作成
  * @param lRequest リクエスト
  * @param lUrl 作成対象のURL
  * @return 作成されたhttpsのフルURL
  * @throws なし
  */
  public static String consHttps(HttpServletRequest lRequest,String lUrl){
    String lPort="";
    if (!SIConfig.SISSL_PORT.equals("443"))lPort=":"+SIConfig.SISSL_PORT;
    return SIConfig.SISSL_SCHEME+"://"+lRequest.getServerName()+lPort+lUrl;
  }
 
  /**
  * <b>consHttp</b>
  * httpのフルURLの作成
  * @param lRequest リクエスト
  * @param lUrl 作成対象のURL
  * @return 作成されたhttpのフルURL
  * @throws なし
  */
  public static String consHttp(HttpServletRequest lRequest,String lUrl){
    String lPort="";
    if (!SIConfig.SINON_SSL_PORT.equals("80"))lPort=":"+SIConfig.SINON_SSL_PORT;
    return SIConfig.SINON_SSL_SCHEME+"://"+lRequest.getServerName()+lPort+lUrl;
  }
  
  /**
  * <b>consURL</b>
  * httpのフルURLの作成
  * @param lRequest リクエスト
  * @param lUrl 作成対象のURL
  * @return 作成されたフルURL
  * @throws なし
  */
  public static String consURL(HttpServletRequest lRequest,String lUrl){
    return consURL(lRequest,lUrl,false);
  }
  
  /**
  * <b>consURL</b>
  * フルURLの作成
  * @param lRequest リクエスト
  * @param lUrl 作成対象のURL
  * @param lEnable httpsの作成フラグ
  * @return 作成されたフルURL
  * @throws なし
  */
  public static String consURL(HttpServletRequest lRequest,String lUrl,boolean lEnable){
    if (SIConfig.SISSL_FLAG_CURRENT ==SIConfig.SISSL_FLAG_DISABLE) return lUrl;
    else if (lEnable) return consHttps(lRequest,lUrl);
    else return consHttp(lRequest,lUrl);
  }
  
  /**
  * <b>isCasherValid</b>
  * 決済の前に、決済情報などが有効でかどうかをチェックします。
  * @param lRequest リクエスト
  * @return 作成されたフルURL
  * @throws なし
  */
  public static boolean cartIsEmpty(HttpServletRequest lRequest){
    HttpSession lSession=lRequest.getSession();
    Object lDetail=lSession.getAttribute(SIConfig.SISESSION_CART_INFO_NAME);//受注明細レコード
    return (lDetail==null);
  }
  
  /**
   * <b>output3kinds</b>
   * @param flg  フラグ
   * @param out1 フラグが"0"の場合の出力文字列
   * @param out2 フラグが"1"の場合の出力文字列
   * @param out3 フラグが"2"の場合の出力文字列
   * @return
   */
  public static String output3kinds(String flg,String out1,String out2,String out3){
    String res = "";
    if(flg.equals("0")){
      res=out1;
    } else if(flg.equals("1")){
      res=out2;
    }else if(flg.equals("2")){
      res=out3;
    }
    return res;
  }
  
  /** ブラウザ不明 */
  public static String BROWSER_UNKNOWN = "0";
  /** ブラウザIE */
  public static String BROWSER_IE = "1";
  /** ブラウザFirefox */
  public static String BROWSER_FIREFOX = "2";
  /** ブラウザOpera */
  public static String BROWSER_OPERA = "3";
  /** ブラウザChrome */
  public static String BROWSER_CHROME = "4";
  /** ブラウザSafari */
  public static String BROWSER_SAFARI = "5";
  /** ブラウザNetscape */
  public static String BROWSER_NETSCAPE = "6";
  
   /** 
    * ブラウザの判定を行います。
    * @param request {@link HttpServletRequest}
    * @return ブラウザを表す文字列
    */
  public static String getBrowser(HttpServletRequest request) {
    String sUserAgent = request.getHeader("user-agent");
    if ( isIE(sUserAgent) ) {
      return BROWSER_IE;
    } else if ( isFirefox(sUserAgent) ) {
      return BROWSER_FIREFOX;
    } else if ( isOpera(sUserAgent) ) {
      return BROWSER_OPERA;
    } else if ( isChrome(sUserAgent) ) {
      return BROWSER_CHROME;
    } else if ( isSafari(sUserAgent) ) {
      return BROWSER_SAFARI;
    } else if ( isNetscape(sUserAgent) ) {
      return BROWSER_NETSCAPE;
    }
    return BROWSER_UNKNOWN;
  }
  
  public static boolean isIE(HttpServletRequest request) {
    return BROWSER_IE.equals(getBrowser(request));
  }
  
  public static boolean isFirefox(HttpServletRequest request) {
    return BROWSER_FIREFOX.equals(getBrowser(request));
  }
  
  public static boolean isOpera(HttpServletRequest request) {
    return BROWSER_OPERA.equals(getBrowser(request));
  }
  
  public static boolean isChrome(HttpServletRequest request) {
    return BROWSER_CHROME.equals(getBrowser(request));
  }
  
  public static boolean isSafari(HttpServletRequest request) {
    return BROWSER_SAFARI.equals(getBrowser(request));
  }
  
  public static boolean isNetscape(HttpServletRequest request) {
    return BROWSER_NETSCAPE.equals(getBrowser(request));
  }
  
  /** 
    * ブラウザがIEであるかどうかの判定を行います。
    * @param sUserAgent ユーザエージェント
    * @return IEであるかどうか
    */
  private static boolean isIE(String sUserAgent) {
    RE re=new RE(".*((MSIE)+ [0-9]\\.[0-9]).*");
    return re.match(sUserAgent);
  }
  
  /**
    * ブラウザがFirefoxであるかどうかの判定を行います。
    * @param sUserAgent ユーザエージェント
    * @return Firefoxであるかどうか
    */
  private static boolean isFirefox(String sUserAgent) {
    RE re=new RE(".*((Firefox/)+[0-9]\\.[0-9]\\.?[0-9]?).*");
    return re.match(sUserAgent);
  }
  
  /**
    * ブラウザがOperaであるかどうかの判定を行います。
    * @param sUserAgent ユーザエージェント
    * @return Opereであるかどうか
    */
  private static boolean isOpera(String sUserAgent) {
    RE re=new RE(".*((Opera)+/? ?[0-9]\\.[0-9][0-9]?).*");
    return re.match(sUserAgent);
  }
  
  /**
    * ブラウザがChromeであるかどうかの判定を行います。
    * @param sUserAgent ユーザエージェント
    * @return Chromeであるかどうか
    */
  private static boolean isChrome(String sUserAgent) {
    RE re=new RE(".*((Chrome)+/?[0-9]\\.?[0-9]?).*");
    return re.match(sUserAgent);
  }
  
  /**
    * ブラウザがSafariであるかどうかの判定を行います。
    * @param sUserAgent ユーザエージェント
    * @return Safariであるかどうか
    */
  private static boolean isSafari(String sUserAgent) {
    RE re=new RE(".*((Version/)+[0-9]\\.?[0-9]?\\.?[0-9]? Safari).*");
    return re.match(sUserAgent);
  }
  
  /**
    * ブラウザがNetscapeであるかどうかの判定を行います。
    * @param sUserAgent ユーザエージェント
    * @return Netscapeであるかどうか
    */
  private static boolean isNetscape(String sUserAgent) {
    RE re=new RE(".*((Netscape)+[0-9]\\.[0-9][0-9]?).*");
    return re.match(sUserAgent);
  }
  
  public static  boolean isHttps(HttpServletRequest request) {
    return request.getScheme().equals("https");
  }
}