project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Team.java
author Medo <smaxein@googlemail.com>
Wed, 11 Jul 2012 01:52:01 +0200
changeset 7328 cd919a2ead4e
parent 6840 c61f842621b8
child 7476 2fb781bbdd51
permissions -rw-r--r--
Hedgeroid: Added experimental lobby chat

/*
 * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
 * Copyright (c) 2011-2012 Richard Deurwaarder <xeli@xelification.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

package org.hedgewars.hedgeroid.Datastructures;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;

import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
import org.hedgewars.hedgeroid.EngineProtocol.PascalExports;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Xml;

public class Team implements Parcelable{

	public static final String DIRECTORY_TEAMS = "teams";
	private static final Integer[] TEAM_COLORS = {
		0xd12b42, /* red    */ 
		0x4980c1, /* blue   */ 
		0x6ab530, /* green  */ 
		0xbc64c4, /* purple */ 
		0xe76d14, /* orange */ 
		0x3fb6e6, /* cyan   */ 
		0xe3e90c, /* yellow */ 
		0x61d4ac, /* mint   */ 
		0xf1c3e1, /* pink   */ 
		/* add new colors here */
	};

//	private static final Integer[] TEAM_COLORS = {
//		0xff0000, /* red    */ 
//		0x00ff00, /* blue   */ 
//		0x0000ff, /* green  */ 
//	};

	private static final int STATE_START = 0;
	private static final int STATE_ROOT = 1;
	private static final int STATE_HOG_ROOT = 2;

	public String name, grave, flag, voice, fort, hash;
	public String file = null;

	public static int maxNumberOfHogs = 0;
	public static int maxNumberOfTeams = 0;

	static{
		maxNumberOfHogs = PascalExports.HWgetMaxNumberOfHogs();
		maxNumberOfTeams = PascalExports.HWgetMaxNumberOfTeams();
	}
	public String[] hats = new String[maxNumberOfHogs];
	public String[] hogNames = new String[maxNumberOfHogs];
	public int[] levels = new int[maxNumberOfHogs];

	public int hogCount = 4;
	public int color = TEAM_COLORS[0];

	public Team(){
	}

	public Team(Parcel in){
		readFromParcel(in);
	}

	@Override
	public boolean equals(Object o){
		if(super.equals(o)) return true;
		else if(o instanceof Team){
			Team t = (Team)o;
			boolean ret = name.equals(t.name);
			ret &= grave.equals(t.grave);
			ret &= flag.equals(t.flag);
			ret &= voice.equals(t.voice);
			ret &= fort.equals(t.fort);
			ret &= hash.equals(t.hash);
			return ret;
		}else{
			return false;
		}
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((grave == null) ? 0 : grave.hashCode());
		result = prime * result + ((flag == null) ? 0 : flag.hashCode());
		result = prime * result + ((voice == null) ? 0 : voice.hashCode());
		result = prime * result + ((fort == null) ? 0 : fort.hashCode());
		result = prime * result + ((hash == null) ? 0 : hash.hashCode());
		return result;
	}

	public void setRandomColor(int[] illegalcolors){
		Integer[] colorsToPickFrom = TEAM_COLORS;
		if(illegalcolors != null){
			ArrayList<Integer> colors = new ArrayList<Integer>();
			for(int color : TEAM_COLORS){
				boolean validColor = true;
				for(int illegal : illegalcolors){
					if(color == illegal) validColor = false;
				}
				if(validColor) colors.add(color);
			}
			if(colors.size() != 0) colorsToPickFrom = colors.toArray(new Integer[1]);
		}
		int index = (int)Math.round(Math.random()*(colorsToPickFrom.length-1));
		color = colorsToPickFrom[index];
	}


	public void sendToEngine(EngineProtocolNetwork epn, int hogCount, int health) throws IOException{
		epn.sendToEngine(String.format("eaddteam %s %d %s", hash, color, name));
		epn.sendToEngine(String.format("egrave %s", grave));
		epn.sendToEngine(String.format("efort %s", fort));
		epn.sendToEngine(String.format("evoicepack %s", voice));
		epn.sendToEngine(String.format("eflag %s", flag));

		for(int i = 0; i < hogCount; i++){
			epn.sendToEngine(String.format("eaddhh %d %d %s", levels[i], health, hogNames[i]));
			epn.sendToEngine(String.format("ehat %s", hats[i]));
		}
	}

	public void setFileName(Context c){
		if(file == null){
		  	file = validFileName(c, name);
		}
	}
	private String validFileName(Context c, String fileName){
		String absolutePath = String.format("%s/%s", c.getFilesDir(), fileName);
		File f = new File(absolutePath);
		if(f.exists()){
			String newFileName = fileName + (int)(Math.random()*10);
			return validFileName(c, newFileName);
		}else{
			return fileName;
		}
	}
	
	/*
	 * XML METHODS
	 */

	/**
	 * Read the xml file path and convert it to a Team object
	 * @param path absolute path to the xml file
	 * @return
	 */
	public static Team getTeamFromXml(String path){
		try {
			XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
			XmlPullParser xmlPuller = xmlPullFactory.newPullParser();

			BufferedReader br = new BufferedReader(new FileReader(path), 1024);
			xmlPuller.setInput(br);
			Team team = new Team();
			int hogCounter = 0;

			int eventType = xmlPuller.getEventType();
			int state = STATE_START;
			while(eventType != XmlPullParser.END_DOCUMENT){
				switch(state){
				case STATE_START:
					if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("team")) state = STATE_ROOT;
					else if(eventType != XmlPullParser.START_DOCUMENT) throwException(path, eventType);
					break;
				case STATE_ROOT:
					if(eventType == XmlPullParser.START_TAG){
						if(xmlPuller.getName().toLowerCase().equals("name")){
							team.name = getXmlText(xmlPuller, "name");
						}else if(xmlPuller.getName().toLowerCase().equals("flag")){
							team.flag= getXmlText(xmlPuller, "flag");
						}else if(xmlPuller.getName().toLowerCase().equals("voice")){
							team.voice = getXmlText(xmlPuller, "voice");
						}else if(xmlPuller.getName().toLowerCase().equals("grave")){
							team.grave = getXmlText(xmlPuller, "grave");
						}else if(xmlPuller.getName().toLowerCase().equals("fort")){
							team.fort = getXmlText(xmlPuller, "fort");
						}else if(xmlPuller.getName().toLowerCase().equals("hash")){
							team.hash = getXmlText(xmlPuller, "hash");
						}else if(xmlPuller.getName().toLowerCase().equals("hog")){
							state = STATE_HOG_ROOT;
						}else throwException(xmlPuller.getName(), eventType);
					}else if(eventType == XmlPullParser.END_TAG) state = STATE_START;
					else throwException(xmlPuller.getText(), eventType);
					break;
				case STATE_HOG_ROOT:
					if(eventType == XmlPullParser.START_TAG){
						if(xmlPuller.getName().toLowerCase().equals("name")){
							team.hogNames[hogCounter] = getXmlText(xmlPuller, "name");
						}else if(xmlPuller.getName().toLowerCase().equals("hat")){
							team.hats[hogCounter] = getXmlText(xmlPuller, "hat");
						}else if(xmlPuller.getName().toLowerCase().equals("level")){
							team.levels[hogCounter] = Integer.parseInt(getXmlText(xmlPuller, "level"));
						}else throwException(xmlPuller.getText(), eventType);
					}else if(eventType == XmlPullParser.END_TAG){
						hogCounter++;
						state = STATE_ROOT;
					}else throwException(xmlPuller.getText(), eventType);
					break;
				}
				eventType = getEventType(xmlPuller);
			}//end while(eventtype != END_DOCUMENT
			return team;
		} catch (NumberFormatException e){
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static String getXmlText(XmlPullParser xmlPuller, String parentTag)throws XmlPullParserException, IOException{
		if(getEventType(xmlPuller) == XmlPullParser.TEXT){
			String txt = xmlPuller.getText();
			if(getEventType(xmlPuller) == XmlPullParser.END_TAG && xmlPuller.getName().toLowerCase().equals(parentTag)){
				return txt;
			}
		}
		throw new XmlPullParserException("malformed xml file on string read from tag: " + parentTag);
	}

	/**
	 * Skips whitespaces..
	 */
	private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
		int eventType = xmlPuller.next();
		while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){
			eventType = xmlPuller.next();
		}
		return eventType;
	}

	private static void throwException(String file, int eventType){
		throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType));
	}

	public void writeToXml(OutputStream os){
		XmlSerializer serializer = Xml.newSerializer();
		try{
			serializer.setOutput(os, "UTF-8");	
			serializer.startDocument("UTF-8", true);
			serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);

			serializer.startTag(null, "team");
			serializer.startTag(null, "name");
			serializer.text(name);
			serializer.endTag(null, "name");
			serializer.startTag(null, "flag");
			serializer.text(flag);
			serializer.endTag(null, "flag");
			serializer.startTag(null, "fort");
			serializer.text(fort);
			serializer.endTag(null, "fort");
			serializer.startTag(null, "grave");
			serializer.text(grave);
			serializer.endTag(null, "grave");
			serializer.startTag(null, "voice");
			serializer.text(voice);
			serializer.endTag(null, "voice");
			serializer.startTag(null, "hash");
			serializer.text(hash);
			serializer.endTag(null, "hash");

			for(int i = 0; i < maxNumberOfHogs; i++){
				serializer.startTag(null, "hog");
				serializer.startTag(null, "name");
				serializer.text(hogNames[i]);
				serializer.endTag(null, "name");
				serializer.startTag(null, "hat");
				serializer.text(hats[i]);
				serializer.endTag(null, "hat");
				serializer.startTag(null, "level");
				serializer.text(String.valueOf(levels[i]));
				serializer.endTag(null, "level");

				serializer.endTag(null, "hog");
			}
			serializer.endTag(null, "team");
			serializer.endDocument();
			serializer.flush();

		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				os.close();
			} catch (IOException e) {}
		}
	}
	/*
	 * END XML METHODS
	 */



	/*
	 * PARCABLE METHODS
	 */

	public int describeContents() {
		return 0;
	}

	public void writeToParcel(Parcel dest, int flags) {
		dest.writeString(name);
		dest.writeString(grave);
		dest.writeString(flag);
		dest.writeString(voice);
		dest.writeString(fort);
		dest.writeString(hash);
		dest.writeStringArray(hats);
		dest.writeStringArray(hogNames);
		dest.writeIntArray(levels);
		dest.writeInt(color);
		dest.writeInt(hogCount);
		dest.writeString(file);
	}


	public void readFromParcel(Parcel src){
		name = src.readString();
		grave = src.readString();
		flag = src.readString();
		voice = src.readString();
		fort = src.readString();
		hash = src.readString();
		src.readStringArray(hats);
		src.readStringArray(hogNames);
		src.readIntArray(levels);
		color = src.readInt();
		hogCount = src.readInt();
		file = src.readString();
	}

	public static final Parcelable.Creator<Team> CREATOR = new Parcelable.Creator<Team>() {
		public Team createFromParcel(Parcel source) {
			return new Team(source);
		}
		public Team[] newArray(int size) {
			return new Team[size];
		}

	};

	/*
	 * END PARCABLE METHODS
	 */

}