/*
 * Copyright (C) 2005-2006 Kouji Sugisawa. All rights reserved.
 */

package jp.sourceforge.livez.imode;

import java.util.ArrayList;
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.ImodeFrame;
import jp.sourceforge.livez.images.ImageType;

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

	private static final long serialVersionUID = 1L;

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

	void setup(final jp.sourceforge.livez.dao.Imode imode) {
		// 名称群を設定します
		this.name			= imode.getName();
		this.productName	= imode.getProductName();
		this.seriesName		= imode.getSeriesName();

		// 画面情報を構築します
		this.screen = new ScreenImpl(imode);

		// 背面画面情報が存在する場合は構築します
		if (imode.getSubscreen() != null)
			this.subScreen = new SubScreenImpl(imode.getSubscreen());

		// ブラウザ情報を設定します
		this.browser.setup(imode);

		// iアプリ情報が存在する場合は構築します
		if (imode.getIappli() != null)
			this.appli = new IappliImpl(imode.getIappli());

		// Flash 情報が存在する場合は構築します
		if (imode.getFlash() != null)
			this.flash = new FlashImpl(imode.getFlash(), imode.getScreenWidth());

		if (imode.getImotion() != null)
			this.imotionType = ImotionType.valueOf(imode.getImotion());

		this.pdf = imode.isPdf();
		this.charaDen = imode.isCharaDen();

		if (imode.getDecomail() != null)
			this.decomail = new DecomailImpl(imode.getDecomail());

		this.toruca = imode.isToruca();
		this.ichannel = imode.isIchannel();

		// 写真フレーム画像情報が存在する場合は構築します
		if (imode.getFrames() != null && imode.getFrames().size() > 0) {
			List<Frame> list = new ArrayList<Frame>(imode.getFrames().size());
			for (ImodeFrame frame : imode.getFrames())
				list.add(new FrameImpl(frame));

			this.frames = list;
		}

		this.menuIcon = imode.isMenuIcon();

		if (imode.getBarcode() != null)
			this.barcode = imode.getBarcode();

		this.ssl = imode.getSsl();

		if (imode.getColor() > 256)
			this.imageTypes.add(ImageType.GIF_8BIT);
		if (imode.getColor() > 4)
			this.imageTypes.add(ImageType.GIF_2BIT);
		if (imode.isJpeg())
			this.imageTypes.add(ImageType.JPEG);
	}

	void setup(final ImodeRequest r) {
		final ImodeUserAgent ua = r.getUserAgent();

		// 名称群を設定します
		this.id		= ua.getId();
		this.name	= ua.getName();

		if (this.seriesName != null)
			this.seriesName = ua.getSeriesName();

		this.vendorId = ua.getVendorId();

		// ブラウザ情報を設定します
		this.browser.setup(ua);

		// リクエスト情報を設定します
		this.type			= ua.getType();
		this.accessType		= ua.getAccessType();
		this.networkType	= ua.getNetworkType();
		this.geoCode		= r.getRoaming();
		this.ser			= ua.getSer();
		this.icc			= ua.getIcc();
		this.userId			= r.getUID();
		this.trustedId		= ua.getTrustedId();

		this.imageTypes.add(ImageType.GIF_1BIT);
	}



	// ---------------------------------------- 静的属性

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

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

	/**
	 * 端末IDを保持します。<p>
	 */
	private String id = null;

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

	/**
	 * 端末名を保持します。<p>
	 */
	private String name = null;

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

	/**
	 * 製品名を保持します。<p>
	 */
	private String productName = null;

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

	/**
	 * シリーズ名を保持します。<p>
	 */
	private String seriesName = null;

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

	/**
	 * ベンダーIDを保持します。<p>
	 */
	private String vendorId = null;

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

	/**
	 * 液晶画面情報を保持します。<p>
	 */
	private ScreenImpl screen = null;

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

	/**
	 * 背面画面情報を保持します。<p>
	 */
	private SubScreenImpl subScreen = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getSubScreen()
	 */
	public SubScreen getSubScreen() {
		return subScreen;
	}

	/**
	 * ブラウザ情報を保持します。<p>
	 */
	private ImodeBrowserImpl browser = new ImodeBrowserImpl();

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

	/**
	 * iアプリ情報を保持します。<p>
	 */
	private IappliImpl appli = null;

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

	/**
	 * Flash Lite 情報を保持します。<p>
	 */
	private FlashImpl flash = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getFlash()
	 */
	public Flash getFlash() {
		return flash;
	}

	/**
	 * iモーション情報を保持します。<p>
	 */
	private ImotionType imotionType = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getImotionType()
	 */
	public ImotionType getImotionType() {
		return imotionType;
	}

	/**
	 * PDF 対応状況を保持します。<p>
	 */
	private boolean pdf = false;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#isPdf()
	 */
	public boolean isPdf() {
		return pdf;
	}

	/**
	 * キャラ電対応状況を保持します。<p>
	 */
	private boolean charaDen = false;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#isCharaDen()
	 */
	public boolean isCharaDen() {
		return charaDen;
	}

	/**
	 * デコメール対応情報を保持します。<p>
	 */
	private Decomail decomail = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getDecomail()
	 */
	public Decomail getDecomail() {
		return decomail;
	}

	/**
	 * トルカ対応状況を保持します。
	 */
	private boolean toruca = false;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#isToruca()
	 */
	public boolean isToruca() {
		return toruca;
	}

	/**
	 * iチャネル対応状況を保持します。
	 */
	private boolean ichannel = false;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#isIchannel()
	 */
	public boolean isIchannel() {
		return ichannel;
	}

	/**
	 * 写真フレーム画像対応情報のリストを保持します。
	 */
	private List<Frame> frames = null;

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

	/**
	 * メニューアイコン対応状況を保持します。
	 */
	private boolean menuIcon = false;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#isMenuIcon()
	 */
	public boolean isMenuIcon() {
		return menuIcon;
	}

	/**
	 * バーコード対応バージョンを保持します。
	 */
	private Float barcode = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getBarcode()
	 */
	public Float getBarcode() {
		return barcode;
	}

	/**
	 * SSL 対応レベルを保持します。
	 */
	private Integer ssl = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getSsl()
	 */
	public Integer getSsl() {
		return ssl;
	}

	/**
	 * 画像形式への対応状況を保持します。
	 */
	private List<ImageType> imageTypes = new ArrayList<ImageType>(4);

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



	// ---------------------------------------- 動的属性

	/**
	 * 端末タイプを保持します。<p>
	 */
	private ImodeType type = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getType()
	 */
	public ImodeType getType() {
		return type;
	}

	/**
	 * 状態コードを保持します。<p>
	 */
	private AccessType accessType = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getAccessType()
	 */
	public AccessType getAccessType() {
		return accessType;
	}

	/**
	 * 通信の種類を保持します。<p>
	 */
	private NetworkType networkType = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getNetworkType()
	 */
	public NetworkType getNetworkType() {
		return networkType;
	}

	/**
	 * ユーザがアクセスしている国番号を保持します。<p>
	 */
	private int geoCode = -1;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getGeoCode()
	 */
	public int getGeoCode() {
		return geoCode;
	}

	/**
	 * 製造番号を保持します。<p>
	 */
	private String ser = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getSer()
	 */
	public String getSer() {
		return ser;
	}

	/**
	 * FOMAカード識別番号を保持します。<p>
	 */
	private String icc = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getIcc()
	 */
	public String getIcc() {
		return icc;
	}

	/**
	 * UID を保持します。<p>
	 */
	private UID userId = null;

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

	/**
	 * トラステッドAPID を保持します。<p>
	 */
	private String trustedId = null;

	/*
	 * @see jp.sourceforge.livez.imode.Imode#getTrustedId()
	 */
	public String getTrustedId() {
		return trustedId;
	}

	@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);
	}

}
