/*
 * Copyright (c) 2005 Kouji Sugisawa. All rights reserved.
 */

package jp.sourceforge.livez.ezweb;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import jp.sourceforge.livez.CarrierType;
import jp.sourceforge.livez.Screen;
import jp.sourceforge.livez.ServiceType;
import jp.sourceforge.livez.dao.EZwebFrame;
import jp.sourceforge.livez.images.ImageType;

/**
 * EZweb を実装したクラスです。
 * 
 * @author 杉澤 浩二
 */
final class EZwebImpl implements EZweb {

	private static final long serialVersionUID = 1L;

	/**
	 * デフォルトコンストラクタです。
	 */
	public EZwebImpl() {}

	void setup(final jp.sourceforge.livez.dao.EZweb ezweb) {
		this.id = ezweb.getDeviceType();
		this.productName = ezweb.getProductName();
		this.seriesName = ezweb.getSeriesName();
		this.screen.setup(ezweb);

		if (ezweb.getFrames() != null && ezweb.getFrames().size() > 0) {
			List<Frame> list = new ArrayList<Frame>(ezweb.getFrames().size());
			for (EZwebFrame frame : ezweb.getFrames())
				list.add(new FrameImpl(frame));

			this.frames = list;
		}

		if (ezweb.getStamp() != null)
			this.stamp = new StampImpl(ezweb.getStamp());

		if (ezweb.isBmp1bit())
			this.imageTypes.add(ImageType.BMP_1BIT);
		if (ezweb.isBmp2bit())
			this.imageTypes.add(ImageType.BMP_2BIT);
		if (ezweb.isPng8bit())
			this.imageTypes.add(ImageType.PNG_8BIT);
		if (ezweb.isJpeg())
			this.imageTypes.add(ImageType.JPEG);
		if (ezweb.isGif())
			this.imageTypes.add(ImageType.GIF_8BIT);
	}

	/**
	 * まとめてau支払い非対応端末のデバイスタイプです。
	 */
	private static final List<String> NON_PREMIUM_EZ = Arrays.asList(new String[] {
		"HI01",	// C201H
		"HI02",	// C201H
		"DN01",	// C202DE
		"TS11",	// C301T
		"HI11",	// C302H
		"CA11",	// C303CA
		"SY11",	// C304SA
		"SN11",	// C305S
		"KC11",	// C307K
		"MA11",	// C308P
		"MA12",	// C308P
		"HI12",	// C309H
		"TS12",	// C310T
		"CA12",	// C311CA
		"KC12"	// C313K
	});

	void setup(final EZwebRequest r) {
		final EZwebUserAgent ua = r.getUserAgent();
		final EZwebMultiMedia media = r.getDataFormat();

		// キャリア情報を設定します。
		switch (ua.getId().charAt(2)) {
			case 'T':
			case 'U':
				this.carrierType = CarrierType.TUKA;
				break;
			default:
				this.carrierType = CarrierType.AU;
				this.premiumEZ = !NON_PREMIUM_EZ.contains(ua.getId());
				break;
		}

		this.id = ua.getId();
		this.screen.setup(r);
		this.softkeys = r.getSoftkeys();
		this.softkeyLabelLength = r.getSoftkeyLabelLength();

		this.browser = new EZwebBrowserImpl(r);

		if (media.getJava() > 0 || media.getBrew() > 0)
			this.appli = new EZappliImpl(media);

		this.dataFormat = media;
		this.userId = r.getSubscriberID();
	}

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getServiceType()
	 */
	public ServiceType getServiceType() {
		return ServiceType.EZWEB;
	}

	/**
	 * キャリアタイプを保持します。
	 */
	private CarrierType carrierType = null;

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getCarrierType()
	 */
	public CarrierType getCarrierType() {
		return carrierType;
	}

	private String id = null;

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getId()
	 */
	public String getId() {
		return id;
	}

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getName()
	 */
	public String getName() {
		return id;
	}

	private String productName = null;

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getProductName()
	 */
	public String getProductName() {
		return productName;
	}

	private String seriesName = null;

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getSeriesName()
	 */
	public String getSeriesName() {
		return seriesName;
	}

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getVendorId()
	 */
	public String getVendorId() {
		return null;
	}

	private ScreenImpl screen = new ScreenImpl();

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getScreen()
	 */
	public Screen getScreen() {
		return screen;
	}

	private int softkeys = 0;

	/*
	 * @see jp.sourceforge.livez.ezweb.EZweb#getSoftkeys()
	 */
	public int getSoftkeys() {
		return softkeys;
	}

    private int softkeyLabelLength = 0;

    /*
     * @see jp.sourceforge.livez.ezweb.EZweb#getSoftkeyLabelLength()
     */
	public int getSoftkeyLabelLength() {
		return softkeyLabelLength;
	}

	private EZwebBrowserImpl browser = null;

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getBrowser()
	 */
	public EZwebBrowser getBrowser() {
		return browser;
	}

	private EZappliImpl appli = null;

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getAppli()
	 */
	public EZappli getAppli() {
		return appli;
	}

	private List<Frame> frames = null;

	/*
	 * @see jp.sourceforge.livez.ezweb.EZweb#getFrames()
	 */
	public List<Frame> getFrames() {
		return frames;
	}

	private Stamp stamp = null;

	/*
	 * @see jp.sourceforge.livez.ezweb.EZweb#getStamp()
	 */
	public Stamp getStamp() {
		return stamp;
	}

	private List<ImageType> imageTypes = new ArrayList<ImageType>(4);

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getEnableImageTypes()
	 */
	public List<ImageType> getEnableImageTypes() {
		return imageTypes;
	}

	private EZwebMultiMedia dataFormat = null;

	/*
	 * @see jp.sourceforge.livez.ezweb.EZweb#getDataFormat()
	 */
	public EZwebMultiMedia getDataFormat() {
		return dataFormat;
	}

	/**
	 * EZ番号(旧サブスクライバID)を保持します。
	 */
	private SubscriberId userId = null;

	/*
	 * @see jp.sourceforge.livez.MobilePhone#getUserId()
	 */
	public SubscriberId getUserId() {
		return userId;
	}

	/**
	 * まとめてau支払い対応状況を保持します。
	 */
	private boolean premiumEZ = false;

	/*
	 * @see jp.sourceforge.livez.ezweb.EZweb#isPremiumEZ()
	 */
	public boolean isPremiumEZ() {
		return premiumEZ;
	}

	@Override
	public int hashCode() {
		return HashCodeBuilder.reflectionHashCode(this);
	}

	@Override
	public boolean equals(final Object obj) {
		return EqualsBuilder.reflectionEquals(this, obj);
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
	}

}
