/*******************************************************************************
 * Copyright (c) 2008 IGA Tosiki, NTT DATA BUSINESS BRAINS Corp.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IGA Tosiki (NTT DATA BUSINESS BRAINS Corp.) - initial API and implementation
 *******************************************************************************/
/*
 * blanco Framework
 * Copyright (C) 2008 NTT DATA BUSINESS BRAINS CORPORATION
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.html.parser.helper;

import java.io.IOException;
import java.util.List;
import java.util.StringTokenizer;

import blanco.commons.util.BlancoStringUtil;
import blanco.html.parser.BlancoHtmlContentHandler;
import blanco.html.parser.valueobject.BlancoHtmlAttribute;

/**
 *文字エンコーディングを判断する HTMLコンテンツハンドラー。
 * 
 * @author IGA Tosiki
 */
public class BlancoHtmlDecideEncodingContentHandler implements
        BlancoHtmlContentHandler {
    protected String fEncoding = null;

    /**
     * HTML 内を調べた結果の文字エンコーディングを戻します。
     * 
     * @return 文字エンコーディング。見つからなかった場合には null。
     */
    public String getEncoding() {
        return fEncoding;
    }

    public void startDocument() throws IOException {
    }

    public void endDocument() throws IOException {
    }

    public void startElement(final String name,
            final List<BlancoHtmlAttribute> attrs) throws IOException {
        if (BlancoStringUtil.null2Blank(name).toLowerCase().equals("meta")) {
            boolean isInContentType = false;
            String content = null;

            for (BlancoHtmlAttribute attr : attrs) {
                if (attr.getName().toLowerCase().equals("http-equiv")) {
                    if ("content-type".equals(BlancoStringUtil.null2Blank(
                            attr.getValue()).toLowerCase())) {
                        // コンテンツ・タイプのmetaと判定。
                        isInContentType = true;
                    }
                }

                if (attr.getName().toLowerCase().equals("content")) {
                    content = attr.getValue();
                }
            }

            if (isInContentType && content != null) {
                parseMetaContentTypeEncoding(content);
            }
        }
    }

    public void endElement(final String name) throws IOException {
    }

    public void characters(final String argCharacters) throws IOException {
    }

    public void comments(final String argComments, final int argType)
            throws IOException {
    }

    /**
     * meta の Content-Type の content から文字エンコーディングを読み取ります。
     * 
     * @param argContent
     */
    protected void parseMetaContentTypeEncoding(final String argContent) {
        final StringTokenizer contentParams = new StringTokenizer(
                BlancoStringUtil.null2Blank(argContent), ";");
        for (; contentParams.hasMoreTokens();) {
            final String nextParam = contentParams.nextToken();

            final StringTokenizer contentParam = new StringTokenizer(
                    BlancoStringUtil.null2Blank(nextParam), "=");
            if (contentParam.hasMoreTokens()) {
                final String paramKey = contentParam.nextToken();
                if (paramKey.trim().toLowerCase().equals("charset")) {
                    if (contentParam.hasMoreTokens()) {
                        final String paramValue = contentParam.nextToken();
                        if (fEncoding == null) {
                            fEncoding = paramValue.trim();
                            // System.out.println("encoding発見["
                            // + fEncoding + "]");
                            break;
                        }
                    }
                }
            }
        }
    }
}
