/*
   Defines base attributes of a bookmark object

   Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz

   This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
   If a copy of the MPL was not distributed with this file, You can obtain one at
   http://mozilla.org/MPL/2.0/.
*/

package com.freerdp.freerdpcore.domain;

import android.content.SharedPreferences;
import android.os.Parcel;
import android.os.Parcelable;

import com.freerdp.freerdpcore.application.GlobalApp;

import java.util.Locale;

public class BookmarkBase implements Parcelable, Cloneable
{
	public static final int TYPE_INVALID = -1;
	public static final int TYPE_MANUAL = 1;
	public static final int TYPE_QUICKCONNECT = 2;
	public static final int TYPE_CUSTOM_BASE = 1000;
	public static final Parcelable.Creator<BookmarkBase> CREATOR =
	    new Parcelable.Creator<BookmarkBase>() {
		    public BookmarkBase createFromParcel(Parcel in)
		    {
			    return new BookmarkBase(in);
		    }

		    @Override public BookmarkBase[] newArray(int size)
		    {
			    return new BookmarkBase[size];
		    }
	    };
	protected int type;
	private long id;
	private String label;
	private String username;
	private String password;
	private String domain;
	private ScreenSettings screenSettings;
	private PerformanceFlags performanceFlags;
	private AdvancedSettings advancedSettings;
	private DebugSettings debugSettings;
	private String hostname;
	private int port;
	private boolean enableGatewaySettings;
	private GatewaySettings gatewaySettings;
	private boolean directConnect;

	public BookmarkBase(Parcel parcel)
	{
		type = parcel.readInt();
		id = parcel.readLong();
		label = parcel.readString();
		username = parcel.readString();
		password = parcel.readString();
		domain = parcel.readString();

		screenSettings = parcel.readParcelable(ScreenSettings.class.getClassLoader());
		performanceFlags = parcel.readParcelable(PerformanceFlags.class.getClassLoader());
		advancedSettings = parcel.readParcelable(AdvancedSettings.class.getClassLoader());
		debugSettings = parcel.readParcelable(DebugSettings.class.getClassLoader());
		hostname = parcel.readString();
		port = parcel.readInt();
		enableGatewaySettings = (parcel.readInt() == 1);
		gatewaySettings = parcel.readParcelable(GatewaySettings.class.getClassLoader());
		directConnect = (parcel.readInt() == 1);
	}

	public BookmarkBase()
	{
		init();
	}

	private void init()
	{
		type = TYPE_MANUAL;
		id = -1;
		label = "";
		username = "";
		password = "";
		domain = "";

		screenSettings = new ScreenSettings();
		performanceFlags = new PerformanceFlags();
		advancedSettings = new AdvancedSettings();
		debugSettings = new DebugSettings();

		hostname = "";
		port = 3389;
		enableGatewaySettings = false;
		gatewaySettings = new GatewaySettings();
		directConnect = false;
	}

	public int getType()
	{
		return type;
	}

	public void setType(int type)
	{
		this.type = type;
	}

	public long getId()
	{
		return id;
	}

	public void setId(long id)
	{
		this.id = id;
	}

	public String getLabel()
	{
		return label;
	}

	public void setLabel(String label)
	{
		this.label = label;
	}

	public String getUsername()
	{
		return username;
	}

	public void setUsername(String username)
	{
		this.username = username;
	}

	public String getPassword()
	{
		return password;
	}

	public void setPassword(String password)
	{
		this.password = password;
	}

	public String getDomain()
	{
		return domain;
	}

	public void setDomain(String domain)
	{
		this.domain = domain;
	}

	public ScreenSettings getScreenSettings()
	{
		return screenSettings;
	}

	public void setScreenSettings(ScreenSettings screenSettings)
	{
		this.screenSettings = screenSettings;
	}

	public PerformanceFlags getPerformanceFlags()
	{
		return performanceFlags;
	}

	public void setPerformanceFlags(PerformanceFlags performanceFlags)
	{
		this.performanceFlags = performanceFlags;
	}

	public AdvancedSettings getAdvancedSettings()
	{
		return advancedSettings;
	}

	public void setAdvancedSettings(AdvancedSettings advancedSettings)
	{
		this.advancedSettings = advancedSettings;
	}

	public DebugSettings getDebugSettings()
	{
		return debugSettings;
	}

	public void setDebugSettings(DebugSettings debugSettings)
	{
		this.debugSettings = debugSettings;
	}

	public String getHostname()
	{
		return hostname;
	}

	public void setHostname(String hostname)
	{
		this.hostname = hostname;
	}

	public int getPort()
	{
		return port;
	}

	public void setPort(int port)
	{
		this.port = port;
	}

	public boolean getEnableGatewaySettings()
	{
		return enableGatewaySettings;
	}

	public void setEnableGatewaySettings(boolean enableGatewaySettings)
	{
		this.enableGatewaySettings = enableGatewaySettings;
	}

	public GatewaySettings getGatewaySettings()
	{
		return gatewaySettings;
	}

	public void setGatewaySettings(GatewaySettings gatewaySettings)
	{
		this.gatewaySettings = gatewaySettings;
	}

	public boolean isDirectConnect()
	{
		return directConnect;
	}

	public void setDirectConnect(boolean directConnect)
	{
		this.directConnect = directConnect;
	}

	public ScreenSettings getActiveScreenSettings()
	{
		return (GlobalApp.IsMeteredNetwork && advancedSettings.getEnable3GSettings())
		    ? advancedSettings.getScreen3G()
		    : screenSettings;
	}

	public PerformanceFlags getActivePerformanceFlags()
	{
		return (GlobalApp.IsMeteredNetwork && advancedSettings.getEnable3GSettings())
		    ? advancedSettings.getPerformance3G()
		    : performanceFlags;
	}

	@Override public int describeContents()
	{
		return 0;
	}

	@Override public void writeToParcel(Parcel out, int flags)
	{
		out.writeInt(type);
		out.writeLong(id);
		out.writeString(label);
		out.writeString(username);
		out.writeString(password);
		out.writeString(domain);

		out.writeParcelable(screenSettings, flags);
		out.writeParcelable(performanceFlags, flags);
		out.writeParcelable(advancedSettings, flags);
		out.writeParcelable(debugSettings, flags);
		out.writeString(hostname);
		out.writeInt(port);
		out.writeInt(enableGatewaySettings ? 1 : 0);
		out.writeParcelable(gatewaySettings, flags);
		out.writeInt(directConnect ? 1 : 0);
	}

	// write to shared preferences
	public void writeToSharedPreferences(SharedPreferences sharedPrefs)
	{

		Locale locale = Locale.ENGLISH;

		SharedPreferences.Editor editor = sharedPrefs.edit();
		editor.clear();
		editor.putString("bookmark.label", label);
		editor.putString("bookmark.username", username);
		editor.putString("bookmark.password", password);
		editor.putString("bookmark.domain", domain);

		editor.putInt("bookmark.colors", screenSettings.getColors());
		editor.putString("bookmark.resolution",
		                 screenSettings.getResolutionString().toLowerCase(locale));
		editor.putInt("bookmark.width", screenSettings.getWidth());
		editor.putInt("bookmark.height", screenSettings.getHeight());

		editor.putBoolean("bookmark.perf_remotefx", performanceFlags.getRemoteFX());
		editor.putBoolean("bookmark.perf_gfx", performanceFlags.getGfx());
		editor.putBoolean("bookmark.perf_gfx_h264", performanceFlags.getH264());
		editor.putBoolean("bookmark.perf_wallpaper", performanceFlags.getWallpaper());
		editor.putBoolean("bookmark.perf_font_smoothing", performanceFlags.getFontSmoothing());
		editor.putBoolean("bookmark.perf_desktop_composition",
		                  performanceFlags.getDesktopComposition());
		editor.putBoolean("bookmark.perf_window_dragging", performanceFlags.getFullWindowDrag());
		editor.putBoolean("bookmark.perf_menu_animation", performanceFlags.getMenuAnimations());
		editor.putBoolean("bookmark.perf_themes", performanceFlags.getTheming());

		editor.putBoolean("bookmark.enable_3g_settings", advancedSettings.getEnable3GSettings());

		editor.putInt("bookmark.colors_3g", advancedSettings.getScreen3G().getColors());
		editor.putString("bookmark.resolution_3g",
		                 advancedSettings.getScreen3G().getResolutionString().toLowerCase(locale));
		editor.putInt("bookmark.width_3g", advancedSettings.getScreen3G().getWidth());
		editor.putInt("bookmark.height_3g", advancedSettings.getScreen3G().getHeight());

		editor.putBoolean("bookmark.perf_remotefx_3g",
		                  advancedSettings.getPerformance3G().getRemoteFX());
		editor.putBoolean("bookmark.perf_gfx_3g", advancedSettings.getPerformance3G().getGfx());
		editor.putBoolean("bookmark.perf_gfx_h264_3g",
		                  advancedSettings.getPerformance3G().getH264());
		editor.putBoolean("bookmark.perf_wallpaper_3g",
		                  advancedSettings.getPerformance3G().getWallpaper());
		editor.putBoolean("bookmark.perf_font_smoothing_3g",
		                  advancedSettings.getPerformance3G().getFontSmoothing());
		editor.putBoolean("bookmark.perf_desktop_composition_3g",
		                  advancedSettings.getPerformance3G().getDesktopComposition());
		editor.putBoolean("bookmark.perf_window_dragging_3g",
		                  advancedSettings.getPerformance3G().getFullWindowDrag());
		editor.putBoolean("bookmark.perf_menu_animation_3g",
		                  advancedSettings.getPerformance3G().getMenuAnimations());
		editor.putBoolean("bookmark.perf_themes_3g",
		                  advancedSettings.getPerformance3G().getTheming());

		editor.putBoolean("bookmark.redirect_sdcard", advancedSettings.getRedirectSDCard());
		editor.putInt("bookmark.redirect_sound", advancedSettings.getRedirectSound());
		editor.putBoolean("bookmark.redirect_microphone", advancedSettings.getRedirectMicrophone());
		editor.putInt("bookmark.security", advancedSettings.getSecurity());
		editor.putString("bookmark.remote_program", advancedSettings.getRemoteProgram());
		editor.putString("bookmark.work_dir", advancedSettings.getWorkDir());
		editor.putBoolean("bookmark.console_mode", advancedSettings.getConsoleMode());

		editor.putBoolean("bookmark.async_channel", debugSettings.getAsyncChannel());
		editor.putBoolean("bookmark.async_update", debugSettings.getAsyncUpdate());
		editor.putString("bookmark.debug_level", debugSettings.getDebugLevel());

		editor.putString("bookmark.hostname", hostname);
		editor.putInt("bookmark.port", port);
		editor.putBoolean("bookmark.enable_gateway_settings", enableGatewaySettings);
		editor.putString("bookmark.gateway_hostname", gatewaySettings.getHostname());
		editor.putInt("bookmark.gateway_port", gatewaySettings.getPort());
		editor.putString("bookmark.gateway_username", gatewaySettings.getUsername());
		editor.putString("bookmark.gateway_password", gatewaySettings.getPassword());
		editor.putString("bookmark.gateway_domain", gatewaySettings.getDomain());

		editor.apply();
	}

	// read from shared preferences
	public void readFromSharedPreferences(SharedPreferences sharedPrefs)
	{
		label = sharedPrefs.getString("bookmark.label", "");
		username = sharedPrefs.getString("bookmark.username", "");
		password = sharedPrefs.getString("bookmark.password", "");
		domain = sharedPrefs.getString("bookmark.domain", "");

		screenSettings.setColors(sharedPrefs.getInt("bookmark.colors", 16));
		screenSettings.setResolution(sharedPrefs.getString("bookmark.resolution", "automatic"),
		                             sharedPrefs.getInt("bookmark.width", 800),
		                             sharedPrefs.getInt("bookmark.height", 600));

		performanceFlags.setRemoteFX(sharedPrefs.getBoolean("bookmark.perf_remotefx", false));
		performanceFlags.setGfx(sharedPrefs.getBoolean("bookmark.perf_gfx", true));
		performanceFlags.setH264(sharedPrefs.getBoolean("bookmark.perf_gfx_h264", true));
		performanceFlags.setWallpaper(sharedPrefs.getBoolean("bookmark.perf_wallpaper", false));
		performanceFlags.setFontSmoothing(
		    sharedPrefs.getBoolean("bookmark.perf_font_smoothing", false));
		performanceFlags.setDesktopComposition(
		    sharedPrefs.getBoolean("bookmark.perf_desktop_composition", false));
		performanceFlags.setFullWindowDrag(
		    sharedPrefs.getBoolean("bookmark.perf_window_dragging", false));
		performanceFlags.setMenuAnimations(
		    sharedPrefs.getBoolean("bookmark.perf_menu_animation", false));
		performanceFlags.setTheming(sharedPrefs.getBoolean("bookmark.perf_themes", false));

		advancedSettings.setEnable3GSettings(
		    sharedPrefs.getBoolean("bookmark.enable_3g_settings", false));

		advancedSettings.getScreen3G().setColors(sharedPrefs.getInt("bookmark.colors_3g", 16));
		advancedSettings.getScreen3G().setResolution(
		    sharedPrefs.getString("bookmark.resolution_3g", "automatic"),
		    sharedPrefs.getInt("bookmark.width_3g", 800),
		    sharedPrefs.getInt("bookmark.height_3g", 600));

		advancedSettings.getPerformance3G().setRemoteFX(
		    sharedPrefs.getBoolean("bookmark.perf_remotefx_3g", false));
		advancedSettings.getPerformance3G().setGfx(
		    sharedPrefs.getBoolean("bookmark.perf_gfx_3g", false));
		advancedSettings.getPerformance3G().setH264(
		    sharedPrefs.getBoolean("bookmark.perf_gfx_h264_3g", false));
		advancedSettings.getPerformance3G().setWallpaper(
		    sharedPrefs.getBoolean("bookmark.perf_wallpaper_3g", false));
		advancedSettings.getPerformance3G().setFontSmoothing(
		    sharedPrefs.getBoolean("bookmark.perf_font_smoothing_3g", false));
		advancedSettings.getPerformance3G().setDesktopComposition(
		    sharedPrefs.getBoolean("bookmark.perf_desktop_composition_3g", false));
		advancedSettings.getPerformance3G().setFullWindowDrag(
		    sharedPrefs.getBoolean("bookmark.perf_window_dragging_3g", false));
		advancedSettings.getPerformance3G().setMenuAnimations(
		    sharedPrefs.getBoolean("bookmark.perf_menu_animation_3g", false));
		advancedSettings.getPerformance3G().setTheming(
		    sharedPrefs.getBoolean("bookmark.perf_themes_3g", false));

		advancedSettings.setRedirectSDCard(
		    sharedPrefs.getBoolean("bookmark.redirect_sdcard", false));
		advancedSettings.setRedirectSound(sharedPrefs.getInt("bookmark.redirect_sound", 0));
		advancedSettings.setRedirectMicrophone(
		    sharedPrefs.getBoolean("bookmark.redirect_microphone", false));
		advancedSettings.setSecurity(sharedPrefs.getInt("bookmark.security", 0));
		advancedSettings.setRemoteProgram(sharedPrefs.getString("bookmark.remote_program", ""));
		advancedSettings.setWorkDir(sharedPrefs.getString("bookmark.work_dir", ""));
		advancedSettings.setConsoleMode(sharedPrefs.getBoolean("bookmark.console_mode", false));

		debugSettings.setAsyncChannel(sharedPrefs.getBoolean("bookmark.async_channel", true));
		debugSettings.setAsyncUpdate(sharedPrefs.getBoolean("bookmark.async_update", true));
		debugSettings.setDebugLevel(sharedPrefs.getString("bookmark.debug_level", "INFO"));

		hostname = sharedPrefs.getString("bookmark.hostname", "");
		port = sharedPrefs.getInt("bookmark.port", 3389);
		enableGatewaySettings = sharedPrefs.getBoolean("bookmark.enable_gateway_settings", false);
		gatewaySettings.setHostname(sharedPrefs.getString("bookmark.gateway_hostname", ""));
		gatewaySettings.setPort(sharedPrefs.getInt("bookmark.gateway_port", 443));
		gatewaySettings.setUsername(sharedPrefs.getString("bookmark.gateway_username", ""));
		gatewaySettings.setPassword(sharedPrefs.getString("bookmark.gateway_password", ""));
		gatewaySettings.setDomain(sharedPrefs.getString("bookmark.gateway_domain", ""));
	}

	// Cloneable
	public Object clone()
	{
		try
		{
			return super.clone();
		}
		catch (CloneNotSupportedException e)
		{
			return null;
		}
	}

	// performance flags
	public static class PerformanceFlags implements Parcelable
	{
		public static final Parcelable.Creator<PerformanceFlags> CREATOR =
		    new Parcelable.Creator<PerformanceFlags>() {
			    public PerformanceFlags createFromParcel(Parcel in)
			    {
				    return new PerformanceFlags(in);
			    }

			    @Override public PerformanceFlags[] newArray(int size)
			    {
				    return new PerformanceFlags[size];
			    }
		    };
		private boolean remotefx;
		private boolean gfx;
		private boolean h264;
		private boolean wallpaper;
		private boolean theming;
		private boolean fullWindowDrag;
		private boolean menuAnimations;
		private boolean fontSmoothing;
		private boolean desktopComposition;

		public PerformanceFlags()
		{
			remotefx = false;
			gfx = true;
			h264 = true;
			wallpaper = false;
			theming = false;
			fullWindowDrag = false;
			menuAnimations = false;
			fontSmoothing = false;
			desktopComposition = false;
		}

		public PerformanceFlags(Parcel parcel)
		{
			remotefx = parcel.readInt() == 1;
			gfx = parcel.readInt() == 1;
			h264 = parcel.readInt() == 1;
			wallpaper = parcel.readInt() == 1;
			theming = parcel.readInt() == 1;
			fullWindowDrag = (parcel.readInt() == 1);
			menuAnimations = parcel.readInt() == 1;
			fontSmoothing = parcel.readInt() == 1;
			desktopComposition = parcel.readInt() == 1;
		}

		public boolean getRemoteFX()
		{
			return remotefx;
		}

		public void setRemoteFX(boolean remotefx)
		{
			this.remotefx = remotefx;
		}

		public boolean getGfx()
		{
			return gfx;
		}

		public void setGfx(boolean gfx)
		{
			this.gfx = gfx;
		}

		public boolean getH264()
		{
			return h264;
		}

		public void setH264(boolean h264)
		{
			this.h264 = h264;
		}

		public boolean getWallpaper()
		{
			return wallpaper;
		}

		public void setWallpaper(boolean wallpaper)
		{
			this.wallpaper = wallpaper;
		}

		public boolean getTheming()
		{
			return theming;
		}

		public void setTheming(boolean theming)
		{
			this.theming = theming;
		}

		public boolean getFullWindowDrag()
		{
			return fullWindowDrag;
		}

		public void setFullWindowDrag(boolean fullWindowDrag)
		{
			this.fullWindowDrag = fullWindowDrag;
		}

		public boolean getMenuAnimations()
		{
			return menuAnimations;
		}

		public void setMenuAnimations(boolean menuAnimations)
		{
			this.menuAnimations = menuAnimations;
		}

		public boolean getFontSmoothing()
		{
			return fontSmoothing;
		}

		public void setFontSmoothing(boolean fontSmoothing)
		{
			this.fontSmoothing = fontSmoothing;
		}

		public boolean getDesktopComposition()
		{
			return desktopComposition;
		}

		public void setDesktopComposition(boolean desktopComposition)
		{
			this.desktopComposition = desktopComposition;
		}

		@Override public int describeContents()
		{
			return 0;
		}

		@Override public void writeToParcel(Parcel out, int flags)
		{
			out.writeInt(remotefx ? 1 : 0);
			out.writeInt(gfx ? 1 : 0);
			out.writeInt(h264 ? 1 : 0);
			out.writeInt(wallpaper ? 1 : 0);
			out.writeInt(theming ? 1 : 0);
			out.writeInt(fullWindowDrag ? 1 : 0);
			out.writeInt(menuAnimations ? 1 : 0);
			out.writeInt(fontSmoothing ? 1 : 0);
			out.writeInt(desktopComposition ? 1 : 0);
		}
	}

	// Screen Settings class
	public static class ScreenSettings implements Parcelable
	{
		public static final int FITSCREEN = -2;
		public static final int AUTOMATIC = -1;
		public static final int CUSTOM = 0;
		public static final int PREDEFINED = 1;
		public static final Parcelable.Creator<ScreenSettings> CREATOR =
		    new Parcelable.Creator<ScreenSettings>() {
			    public ScreenSettings createFromParcel(Parcel in)
			    {
				    return new ScreenSettings(in);
			    }

			    @Override public ScreenSettings[] newArray(int size)
			    {
				    return new ScreenSettings[size];
			    }
		    };
		private int resolution;
		private int colors;
		private int width;
		private int height;

		public ScreenSettings()
		{
			init();
		}

		public ScreenSettings(Parcel parcel)
		{
			resolution = parcel.readInt();
			colors = parcel.readInt();
			width = parcel.readInt();
			height = parcel.readInt();
		}

		private void validate()
		{
			switch (colors)
			{
				case 32:
				case 24:
				case 16:
				case 15:
				case 8:
					break;
				default:
					colors = 32;
					break;
			}

			if ((width <= 0) || (width > 65536))
			{
				width = 1024;
			}

			if ((height <= 0) || (height > 65536))
			{
				height = 768;
			}

			switch (resolution)
			{
				case FITSCREEN:
				case AUTOMATIC:
				case CUSTOM:
				case PREDEFINED:
					break;
				default:
					resolution = AUTOMATIC;
					break;
			}
		}

		private void init()
		{
			resolution = AUTOMATIC;
			colors = 16;
			width = 0;
			height = 0;
		}

		public void setResolution(String resolution, int width, int height)
		{
			if (resolution.contains("x"))
			{
				String[] dimensions = resolution.split("x");
				this.width = Integer.parseInt(dimensions[0]);
				this.height = Integer.parseInt(dimensions[1]);
				this.resolution = PREDEFINED;
			}
			else if (resolution.equalsIgnoreCase("custom"))
			{
				this.width = width;
				this.height = height;
				this.resolution = CUSTOM;
			}
			else if (resolution.equalsIgnoreCase("fitscreen"))
			{
				this.width = this.height = 0;
				this.resolution = FITSCREEN;
			}
			else
			{
				this.width = this.height = 0;
				this.resolution = AUTOMATIC;
			}
		}

		public int getResolution()
		{
			return resolution;
		}

		public void setResolution(int resolution)
		{
			this.resolution = resolution;

			if (resolution == AUTOMATIC || resolution == FITSCREEN)
			{
				width = 0;
				height = 0;
			}
		}

		public String getResolutionString()
		{
			if (isPredefined())
				return (width + "x" + height);

			return (isFitScreen() ? "fitscreen" : isAutomatic() ? "automatic" : "custom");
		}

		public boolean isPredefined()
		{
			validate();
			return (resolution == PREDEFINED);
		}

		public boolean isAutomatic()
		{
			validate();
			return (resolution == AUTOMATIC);
		}

		public boolean isFitScreen()
		{
			validate();
			return (resolution == FITSCREEN);
		}

		public boolean isCustom()
		{
			validate();
			return (resolution == CUSTOM);
		}

		public int getWidth()
		{
			validate();
			return width;
		}

		public void setWidth(int width)
		{
			this.width = width;
		}

		public int getHeight()
		{
			validate();
			return height;
		}

		public void setHeight(int height)
		{
			this.height = height;
		}

		public int getColors()
		{
			validate();
			return colors;
		}

		public void setColors(int colors)
		{
			this.colors = colors;
		}

		@Override public int describeContents()
		{
			return 0;
		}

		@Override public void writeToParcel(Parcel out, int flags)
		{
			out.writeInt(resolution);
			out.writeInt(colors);
			out.writeInt(width);
			out.writeInt(height);
		}
	}

	public static class DebugSettings implements Parcelable
	{

		public static final Parcelable.Creator<DebugSettings> CREATOR =
		    new Parcelable.Creator<DebugSettings>() {
			    public DebugSettings createFromParcel(Parcel in)
			    {
				    return new DebugSettings(in);
			    }

			    @Override public DebugSettings[] newArray(int size)
			    {
				    return new DebugSettings[size];
			    }
		    };
		private String debug;
		private boolean asyncChannel;
		private boolean asyncTransport;
		private boolean asyncUpdate;

		public DebugSettings()
		{
			init();
		}

		// Session Settings
		public DebugSettings(Parcel parcel)
		{
			asyncChannel = parcel.readInt() == 1;
			asyncTransport = parcel.readInt() == 1;
			asyncUpdate = parcel.readInt() == 1;
			debug = parcel.readString();
		}

		private void init()
		{
			debug = "INFO";
			asyncChannel = true;
			asyncTransport = false;
			asyncUpdate = true;
		}

		private void validate()
		{
			final String[] levels = { "OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" };

			for (String level : levels)
			{
				if (level.equalsIgnoreCase(this.debug))
				{
					return;
				}
			}

			this.debug = "INFO";
		}

		public String getDebugLevel()
		{
			validate();
			return debug;
		}

		public void setDebugLevel(String debug)
		{
			this.debug = debug;
		}

		public boolean getAsyncUpdate()
		{
			return asyncUpdate;
		}

		public void setAsyncUpdate(boolean enabled)
		{
			asyncUpdate = enabled;
		}

		public boolean getAsyncChannel()
		{
			return asyncChannel;
		}

		public void setAsyncChannel(boolean enabled)
		{
			asyncChannel = enabled;
		}

		@Override public int describeContents()
		{
			return 0;
		}

		@Override public void writeToParcel(Parcel out, int flags)
		{
			out.writeInt(asyncChannel ? 1 : 0);
			out.writeInt(asyncTransport ? 1 : 0);
			out.writeInt(asyncUpdate ? 1 : 0);
			out.writeString(debug);
		}
	}

	// Session Settings
	public static class AdvancedSettings implements Parcelable
	{
		public static final Parcelable.Creator<AdvancedSettings> CREATOR =
		    new Parcelable.Creator<AdvancedSettings>() {
			    public AdvancedSettings createFromParcel(Parcel in)
			    {
				    return new AdvancedSettings(in);
			    }

			    @Override public AdvancedSettings[] newArray(int size)
			    {
				    return new AdvancedSettings[size];
			    }
		    };
		private boolean enable3GSettings;
		private ScreenSettings screen3G;
		private PerformanceFlags performance3G;
		private boolean redirectSDCard;
		private int redirectSound;
		private boolean redirectMicrophone;
		private int security;
		private boolean consoleMode;
		private String remoteProgram;
		private String workDir;

		public AdvancedSettings()
		{
			init();
		}

		public AdvancedSettings(Parcel parcel)
		{
			enable3GSettings = parcel.readInt() == 1;
			screen3G = parcel.readParcelable(ScreenSettings.class.getClassLoader());
			performance3G = parcel.readParcelable(PerformanceFlags.class.getClassLoader());
			redirectSDCard = parcel.readInt() == 1;
			redirectSound = parcel.readInt();
			redirectMicrophone = parcel.readInt() == 1;
			security = parcel.readInt();
			consoleMode = parcel.readInt() == 1;
			remoteProgram = parcel.readString();
			workDir = parcel.readString();
		}

		private void init()
		{
			enable3GSettings = false;
			screen3G = new ScreenSettings();
			performance3G = new PerformanceFlags();
			redirectSDCard = false;
			redirectSound = 0;
			redirectMicrophone = false;
			security = 0;
			consoleMode = false;
			remoteProgram = "";
			workDir = "";
		}

		private void validate()
		{
			switch (redirectSound)
			{
				case 0:
				case 1:
				case 2:
					break;
				default:
					redirectSound = 0;
					break;
			}

			switch (security)
			{
				case 0:
				case 1:
				case 2:
				case 3:
					break;
				default:
					security = 0;
					break;
			}
		}

		public boolean getEnable3GSettings()
		{
			return enable3GSettings;
		}

		public void setEnable3GSettings(boolean enable3GSettings)
		{
			this.enable3GSettings = enable3GSettings;
		}

		public ScreenSettings getScreen3G()
		{
			return screen3G;
		}

		public void setScreen3G(ScreenSettings screen3G)
		{
			this.screen3G = screen3G;
		}

		public PerformanceFlags getPerformance3G()
		{
			return performance3G;
		}

		public void setPerformance3G(PerformanceFlags performance3G)
		{
			this.performance3G = performance3G;
		}

		public boolean getRedirectSDCard()
		{
			return redirectSDCard;
		}

		public void setRedirectSDCard(boolean redirectSDCard)
		{
			this.redirectSDCard = redirectSDCard;
		}

		public int getRedirectSound()
		{
			validate();
			return redirectSound;
		}

		public void setRedirectSound(int redirect)
		{
			this.redirectSound = redirect;
		}

		public boolean getRedirectMicrophone()
		{
			return redirectMicrophone;
		}

		public void setRedirectMicrophone(boolean redirect)
		{
			this.redirectMicrophone = redirect;
		}

		public int getSecurity()
		{
			validate();
			return security;
		}

		public void setSecurity(int security)
		{
			this.security = security;
		}

		public boolean getConsoleMode()
		{
			return consoleMode;
		}

		public void setConsoleMode(boolean consoleMode)
		{
			this.consoleMode = consoleMode;
		}

		public String getRemoteProgram()
		{
			return remoteProgram;
		}

		public void setRemoteProgram(String remoteProgram)
		{
			this.remoteProgram = remoteProgram;
		}

		public String getWorkDir()
		{
			return workDir;
		}

		public void setWorkDir(String workDir)
		{
			this.workDir = workDir;
		}

		@Override public int describeContents()
		{
			return 0;
		}

		@Override public void writeToParcel(Parcel out, int flags)
		{
			out.writeInt(enable3GSettings ? 1 : 0);
			out.writeParcelable(screen3G, flags);
			out.writeParcelable(performance3G, flags);
			out.writeInt(redirectSDCard ? 1 : 0);
			out.writeInt(redirectSound);
			out.writeInt(redirectMicrophone ? 1 : 0);
			out.writeInt(security);
			out.writeInt(consoleMode ? 1 : 0);
			out.writeString(remoteProgram);
			out.writeString(workDir);
		}
	}

	public static class GatewaySettings implements Parcelable
	{
		public static final Parcelable.Creator<GatewaySettings> CREATOR =
		    new Parcelable.Creator<GatewaySettings>() {
			    public GatewaySettings createFromParcel(Parcel in)
			    {
				    return new GatewaySettings(in);
			    }

			    @Override public GatewaySettings[] newArray(int size)
			    {
				    return new GatewaySettings[size];
			    }
		    };
		private String hostname;
		private int port;
		private String username;
		private String password;
		private String domain;

		public GatewaySettings()
		{
			hostname = "";
			port = 443;
			username = "";
			password = "";
			domain = "";
		}

		public GatewaySettings(Parcel parcel)
		{
			hostname = parcel.readString();
			port = parcel.readInt();
			username = parcel.readString();
			password = parcel.readString();
			domain = parcel.readString();
		}

		public String getHostname()
		{
			return hostname;
		}

		public void setHostname(String hostname)
		{
			this.hostname = hostname;
		}

		public int getPort()
		{
			return port;
		}

		public void setPort(int port)
		{
			this.port = port;
		}

		public String getUsername()
		{
			return username;
		}

		public void setUsername(String username)
		{
			this.username = username;
		}

		public String getPassword()
		{
			return password;
		}

		public void setPassword(String password)
		{
			this.password = password;
		}

		public String getDomain()
		{
			return domain;
		}

		public void setDomain(String domain)
		{
			this.domain = domain;
		}

		@Override public int describeContents()
		{
			return 0;
		}

		@Override public void writeToParcel(Parcel out, int flags)
		{
			out.writeString(hostname);
			out.writeInt(port);
			out.writeString(username);
			out.writeString(password);
			out.writeString(domain);
		}
	}
}
