package com.lloydm.javakogengine_chess;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.Log;

class Resources
{
	//
	//put all resource names in here.....
	public static int THREADRUNNING = 0;
	public static int LOGO = 0;
	public static int FONT = 0;
	public static int SMALLFONT = 0;
	public static int LARGEFONT = 0;
	public static int FOG = 0;
	public static int CLICK = 0;
	public static int blackcat = -1;
	//public static int loadingbk = -1; //27mar2021
	//public static int loadingbar = -1;//27mar2021
	//temporarily do this
	//start-------------//28Feb2021

///////////////////Method Definition///////////////
	public static boolean readbool(String data)
	{
		////////////////////////
		//takes a String that contains 'true' or 'false' and returns a boolean value
		//String is form left identifier=right value
		//swapped if statements around 12sep2021
		if(data.substring(data.indexOf("=") + 1).equals("false"))//this was below the other if block earlier//12sep2021
		{
			return false;
		}
		else
		{
			if(data.substring(data.indexOf("=") + 1).equals("true"))
			{
				return true;
			}
		}
		int i;
		i = Integer.decode(data.substring(data.indexOf("=") + 1));
		if(i<=0)
		{
			return false;
		}
		else
		{
			if(i>0)
			{
				return true;
			}
		}
		return false; //have to return something by default...so make it false by default....
	}
	//end---------------//28Feb2021

///////////////////Method Definition///////////////
	public static int readuint(String data)//2apr2021
	{
		int i;
		i = Integer.decode(data.substring(data.indexOf("=")+1));
		return i;
	
	}
	
///////////////////Method Definition///////////////
	public static int readint(String data)
	{
		//takes a String that contains an int, with no commas or period symbols
		//and converts to an integer.
		//String is of form left identifier=right value
		int i;
		i = Integer.decode(data.substring(data.indexOf("=") + 1));
		return i;
	}

///////////////////Method Definition///////////////
	public static float readfloat(String data)
	{
		//takes a String in 100.01 format (ie one hundred point oh-one)
		//and returns the float value
		//String is of form left identifier=right value
		float i = 1;
		i = Float.parseFloat(data.substring(data.indexOf("=") + 1));
		return i;
	}

///////////////////Method Definition///////////////
	public static String readstring(String data11)
	{
		//simply returns a String from a line that looks like x=abc
		//ie left identifier=right value
		String value = data11.substring(data11.indexOf("=") + 1);
		if(value==null)
		{
			return "";
		}
		else
		{
			return value;
		}
	}

///////////////////Method Definition///////////////
	public static void AssignOffsets(Game game,String file)//20apr2021
	{
		if(file.equals(""))
		{
			return;
		}
		try
		{
			String[] data = Resources.ReadAllLines(file);
			for(int i=0;i<data.length;i++)
			{
				if(data[i].indexOf("=")>0)
				{
					switch(data[i].substring(0,data[i].indexOf("=")))
					{
						case "image":
							String value = readstring(data[i]);
							String[] values = value.split(",");
							if(values!=null)
							{
								if(values.length==3)
								{
									String tmpname = values[0];
									int offx = 0;
									int offy = 0;
									offx = Integer.decode(values[1]);
									offy = Integer.decode(values[2]);
									for(int j=0;j<Game.templates.length;j++)
									{
										if(Game.templates[j].catfile.equals(tmpname))
										{
											Game.templates[j].offx = offx;
											Game.templates[j].offy = offy;
											Game.templates[j].autocalcedoffsets = true;
										}
									}
								}
							}
						break;
					}
				}
			}
		}
		catch(Exception e)
		{
			//String msg = e.Message;
		}
	}
	
	
///////////////////Method Definition///////////////
	public static void LoadGui(Game game, String file)
	{
		////////////////////////
		//load the gui elements into the Game.gui array
		//so that we can reference them later on
		int alti = 0;//11apr2021
		try
		{
			String[] data = Resources.ReadAllLines(file);//13mar2021
			//String[] data = Resources.ReadAllLines(file,System.Text.Encoding.UTF8);//13mar2021
			int count = 0;
			for(int i=0;i<data.length;i++)
			{
				if(data[i].indexOf("=")>0)
				{
					switch(data[i].substring(0,data[i].indexOf("=")))
					{
						case "newgui":
						count++;
						break;
					}
				}
			}
			if(count>0)
			{
				Log.i(Config.TAG,"Gui Count:"+count);
				Game.gui = new Gui[count];
				int id = -1;
				int cw = 0;
				int ch = 0;
				int nw = 0;
				int nh = 0;
				int fontsize = 0;
				int factionindex = 0;//16oct2021
				String fontfile = "";
				for(int i=0;i<data.length;i++)
				{
					if(data[i].indexOf("=")>0)
					{
						//Log.i(Config.TAG," Gui Creation For:"+data[i]);
						switch(data[i].substring(0,data[i].indexOf("=")))
						{
							case "newgui":
							id++;
							Log.i(Config.TAG,"Game.gui[id] about to be created for id:"+id);
							Game.gui[id] = new Gui(game);
							Game.gui[id].reset(game,id);
							Log.i(Config.TAG,"Game.gui[id] created for id:"+id);
							alti = 0;//11apr2021
							break;
							case "factionindex"://16oct2021
							factionindex%=Game.MaxArmies;
							Game.gui[id].factionindex[factionindex] = readint(data[i]);
							factionindex++;
							break;
							case "leftjustify"://16oct2021
							Game.gui[id].leftjustify = readint(data[i]);
							break;
								
							case "type":
							Game.gui[id].type = readint(data[i]);	
							break;
							case "screenname":
							Game.gui[id].screenname = readstring(data[i]);
							break;
							case "missionindex":
							Game.gui[id].missionindex = readint(data[i]);
							break;
							case "index": //28mar2021
							Game.gui[id].index = readint(data[i]); //28mar2021
							break;//28mar2021
							case "techlinkid"://2sep2021
							Game.gui[id].index = readint(data[i]);//2sep2021
							break;//2sep2021
							//start-------------//28Feb2021
							case "missionname":
							Game.gui[id].missionname = readstring(data[i]);
							break;
							//end---------------//28Feb2021
							case "topindexzero": //24Feb2021
							Game.gui[id].topindexzero = (int)Functions.abs(Functions.sign(readint(data[i])));//24Feb2021
							break;//24Feb2021
							case "link":
							Game.gui[id].link = readstring(data[i]);
							break;
							case "command":
							boolean found = false;
							Game.gui[id].command = readstring(data[i]);
							if(Game.gui[id].command.indexOf("buybutton")>=0)
							{
								Game.gui[id].title = "Buy";
							}
							if(Game.gui[id].command.indexOf("buyimage")>=0)
							{
								Game.gui[id].imagefile = "media/mod/rpgb/magicspells.png";//hardcoded garbage...!
								//at least we can overwrite it if we need to with an image command in the text file.....grr.
								found = false;
								for(int j=0;j<id;j++)
								{
									if(Game.gui[j].imagefile.equals(Game.gui[id].imagefile))
									{
										found = true;
										Game.gui[id].image = Game.gui[j].image;
										break;
									}
								}
								if(!found){Game.gui[id].image = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);}
								Game.gui[id].tmpimage = Game.gui[id].image; //30apr2021
							}
							break;
							case "title":
							Game.gui[id].title = readstring(data[i]);
							if(Config.TRANSLATEGUI)//21mar2021
							{
								Game.gui[id].title = Translation.TranslateWord(Game.gui[id].title,false);
							}
							break;
							case "tooltip":
							Game.gui[id].tooltip = readstring(data[i]);
							if(Config.TRANSLATEGUI)//21mar2021
							{
								Game.gui[id].tooltip = Translation.TranslateWord(Game.gui[id].tooltip,false);
							}
							break;
							case "action":
							Game.gui[id].action = readint(data[i]);
							break;
							case "hidden":
							Game.gui[id].hidden = readint(data[i]);
							break;
							case "backgroundrect":
								String[] tmpbk = readstring(data[i]).split(",");
								if(tmpbk.length==7)
								{
									int rx = 0;
									int ry = 0;
									int rw = 0;
									int rh = 0;
									int rgb_r = 0;
									int rgb_b = 0;
									int rgb_g = 0;
									rx = Integer.decode(tmpbk[0]);
									ry = Integer.decode(tmpbk[1]);
									rw = Integer.decode(tmpbk[2]);
									rh = Integer.decode(tmpbk[3]);
									if(Game.GUIHALFRES>1)
									{
										rx/=Game.GUIHALFRES;
										ry/=Game.GUIHALFRES;
										rw/=Game.GUIHALFRES;
										rh/=Game.GUIHALFRES;
									}	
									rgb_r = Integer.decode(tmpbk[4]);
									rgb_g = Integer.decode(tmpbk[5]);
									rgb_b = Integer.decode(tmpbk[6]);
									Game.gui[id].backgroundrect = true;
									Game.gui[id].backgroundrectcoords[0] = rx;
									Game.gui[id].backgroundrectcoords[1] = ry;
									Game.gui[id].backgroundrectcoords[2] = rw;
									Game.gui[id].backgroundrectcoords[3] = rh;
									Game.gui[id].backgroundrectcolor[0] = rgb_r;
									Game.gui[id].backgroundrectcolor[1] = rgb_g;
									Game.gui[id].backgroundrectcolor[2] = rgb_b;
									
								}
							break;
							//start-------------//11mar2021
							case "horizontal":
							Game.gui[id].horizontal = readint(data[i]);
							break;
							case "vertical":
							Game.gui[id].vertical = readint(data[i]);
							break;
							//end---------------//11mar2021
							case "triggerlink":
							Game.gui[id].triggerlink = readint(data[i]);
							break;
							case "mission":
							Game.gui[id].mission = readint(data[i]);
							break;
							case "gamestate":
							Game.gui[id].gamestate = 10000 + readint(data[i]);
							break;
							case "nextscreenname":
							Game.gui[id].nextscreenname = readstring(data[i]);
							break;
							case "nextgamestate":
							Game.gui[id].nextgamestate = 10000 + readint(data[i]);
							break;
							case "x":
							Game.gui[id].x = readint(data[i]);
							break;
							case "y":
							Game.gui[id].y = readint(data[i]);
							break;
							case "w":
							Game.gui[id].w = readint(data[i]);
							break;
							case "h":
							Game.gui[id].h = readint(data[i]);
							break;
							case "cw":
							cw = readint(data[i]);
							break;
							case "ch":
							ch = readint(data[i]);
							break;
							case "nw":
							nw = readint(data[i]);
							break;
							case "nh":
							nh = readint(data[i]);
							break;
							case "altimage":
							//11apr2021 - modified to be an array
							if(alti>4)
							{
								continue;
							}
							Game.gui[id].altimagefile[alti] = readstring(data[i]);
							found = false;
							for(int j=0;j<id;j++)
							{
								for(int k=0;k<alti+1;k++)
								{
									if(Game.gui[j].altimagefile[alti].equals(Game.gui[id].altimagefile[k]))
									{
										found = true;
										Game.gui[id].altimage[alti] = Game.gui[j].altimage[k];
										break;
									}
								}
							}
							for(int j=0;j<id;j++)
							{
								for(int k=0;k<alti+1;k++)
								{
									if(Game.gui[j].imagefile.equals(Game.gui[id].altimagefile[k]))
									{
										found = true;
										Game.gui[id].altimage[alti] = Game.gui[j].image;
										break;
									}
								}
							}
							if(!found){Game.gui[id].altimage[alti] = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);}
							alti++;
							break;
							case "image":
							Game.gui[id].imagefile = readstring(data[i]);
							found = false;
							for(int j=0;j<id;j++)
							{
								if(Game.gui[j].imagefile.equals(Game.gui[id].imagefile))
								{
									found = true;
									Game.gui[id].image = Game.gui[j].image;
									break;
								}
							}
							if(!found){Game.gui[id].image = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);}
							Game.gui[id].tmpimage = Game.gui[id].image; //30apr2021
							break;
							case "scale":
							Game.gui[id].scale = readfloat(data[i]);
							break;
							case "font":
							fontfile = readstring(data[i]);
							Game.gui[id].fontfile = fontfile;
							break;
							case "ptsize":
							fontsize = readint(data[i]);
							Game.gui[id].fontsize = fontsize;// * Config.FONTALIAS;
							break;
							case "loadfont":
							found = false;
							for(int j=0;j<id;j++)
							{
								if(Game.gui[j].fontfile.equals(Game.gui[id].fontfile) && Game.gui[j].fontsize==Game.gui[id].fontsize)
								{
									found = true;
									Game.gui[id].font = Game.gui[j].font;
									break;
								}
							}
							if(!found)
							{
								if(!fontfile.equals("") && fontsize>0)
								{
									Game.gui[id].font = Resources.LoadFont(game,fontfile,fontsize);
								}
							}
							fontfile = "";
							fontsize = 0;
							break;
						}
					}
				}
				Log.i(Config.TAG,"Gui Total Length:"+id);
			}
			LocalStorage.setitem("FILE LOAD:"+file,"SUCCESS");//24mar2021
		}
		catch(Exception e)
		{
			Log.i(Config.TAG,"403:"+e.getMessage());
			LocalStorage.setitem("FILE LOAD:"+file,"FAILED");//24mar2021
		}
		//post processing
		Gui.ResetStores();
		if(Game.GUIHALFRES>1)//25sep2021
		{
			for(int i=0;i<Game.gui.length;i++)
			{
				Game.gui[i].x/=Game.GUIHALFRES;
				Game.gui[i].y/=Game.GUIHALFRES;
				Game.gui[i].w/=Game.GUIHALFRES;
				Game.gui[i].h/=Game.GUIHALFRES;
				Game.gui[i].scale/=Game.GUIHALFRES;
			}
		}
	}

///////////////////Method Definition///////////////
	public static String[] processextraunits() //7mar2021
	{
		////////////////////////
		//in the config files we can have multiple lines indicating
		//multiple files for creatures and so forth
		//this method handles getting this data before we create all our
		//templates in LoadTemplates
		String[] data = new String[0];
		try
		{
			String[] config = Resources.ReadAllLines(Config.configfile);
			for(int i=0;i<config.length;i++)
			{
				if(config[i].indexOf("=")>0)
				{
					switch(config[i].substring(0,config[i].indexOf("=")))
					{
						case "extraunits":
						try
						{
							String filename = readstring(config[i]);
							String[] data2 = Resources.ReadAllLines(filename);
							if(data2!=null && data2.length>0)
							{
								int ii = data.length;
								data = (String[])ArrayResize.Resize(data,data.length + data2.length); //11apr2021
								for(int j=0;j<data2.length;j++)
								{
									data[ii + j] = data2[j];
								}				
							}
						}
						catch(Exception f)
						{
							//Log.i(Config.TAG,"Error:"+f.Message);
						}
						break;
					}
				}
			}
		}
		catch(Exception e)
		{
			//Log.i(Config.TAG,"Error:"+e.Message);
		}
		return data;
	}
	
///////////////////Method Definition///////////////
	public static void LoadTech(Game game, String file) //2sep2021
	{
		////////////////////////
		//load all the tech templates
		//that we will use in the Game.
		try
		{
			String[] data = Resources.ReadAllLines(file);
			int count = 0;
			for(int i=0;i<data.length;i++)
			{
				if(data[i].indexOf("=")>0)
				{
					switch(data[i].substring(0,data[i].indexOf("=")))
					{
						case "newtech":
						count++;
						break;							
					}
				}
			}
			if(count>0)
			{
				Game.techs = new Tech[count];
				int id = -1;
				for(int i=0;i<data.length;i++)
				{
					//Unit Template.....
					if(data[i].indexOf("=")>0)
					{
						switch(data[i].substring(0,data[i].indexOf("=")))
						{
						
							case "newtech":
							id++;
							Game.techs[id] = new Tech();
							Game.techs[id].reset(game,id,false);
							Game.techs[id].name = readstring(data[i]);
							Game.techs[id].description = readstring(data[i]).split("\\|");
							Log.i(Config.TAG,"Loading Techs:");
							Log.i(Config.TAG,"Name:"+Game.techs[id].name);
							count++;
							break;	
							case "description":
							Game.techs[id].description = readstring(data[i]).split("\\|");
							break;
							case "tooltip":
							Game.techs[id].tooltip = readstring(data[i]);
							break;
							case "displayname":
							Game.techs[id].displayname = readstring(data[i]);
							break;
							case "techcategory"://23sep2021
							Game.techs[id].techcategory = readstring(data[i]);
							Log.i(Config.TAG,"Tech Class:"+Game.techs[id].techcategory);
							case "cellwidth":
							Game.techs[id].cw = readint(data[i]);
							break;
							case "cellheight":
							Game.techs[id].ch = readint(data[i]);
							break;
							case "cellswide":
							Game.techs[id].nw = readint(data[i]);
							break;
							case "cellshigh":
							Game.techs[id].nh = readint(data[i]);
							break;
							//start----------//23sep2021
							case "salecellwidth":
							Game.techs[id].scw = readint(data[i]);
							break;
							case "salecellheight":
							Game.techs[id].sch = readint(data[i]);
							break;
							case "salecellswide":
							Game.techs[id].snw = readint(data[i]);
							break;
							case "salecellshigh":
							Game.techs[id].snh = readint(data[i]);
							break;
							//end----------//23sep2021
							case "effectname":
							Game.techs[id].effectname = readstring(data[i]);
							break;
							case "effectint":
							Game.techs[id].effectint = readint(data[i]);
							break;
							case "parseeffect": //needed to parse the effect name and apply the effect int as required....
							Tech.parseeffect(game,id);
							break;
							case "researchtime":
							Game.techs[id].researchtime = 60 * readint(data[i]); //multiply by frames per second....
							break;
							case "image":
							Game.techs[id].imgfile = readstring(data[i]);
							boolean found = false;
							for(int j=0;j<id;j++)
							{
								if(Game.techs[j].imgfile.equals(Game.techs[id].imgfile))
								{
									found = true;
									Game.techs[id].img = Game.techs[j].img;
									break;
								}
							}
							if(!found)
							{
								Game.techs[id].img = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,Game.techs[id].cw,Game.techs[id].ch,Game.techs[id].nw,Game.techs[id].nh);
							}
							break;
							//start----------//23sep2021
							case "saleimage"://23sep2021
							Game.techs[id].saleimgfile = readstring(data[i]);
							found = false;
							for(int j=0;j<id;j++)
							{
								if(Game.techs[j].saleimgfile.equals(Game.techs[id].saleimgfile))
								{
									found = true;
									Game.techs[id].saleimg = Game.techs[j].saleimg;
									break;
								}
							}
							if(!found)
							{
								Game.techs[id].saleimg = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,Game.techs[id].scw,Game.techs[id].sch,Game.techs[id].snw,Game.techs[id].snh);
							}
							break;
							case "saleframe":
							Game.techs[id].saleimgframe = readint(data[i]);
							break;
							//end------------//23sep2021
							case "frame":
							Game.techs[id].imgframe = readint(data[i]);
							break;
							case "guilinkid":
							Game.techs[id].guilinkid = readint(data[i]);
							break;
							case "faction":
							Game.techs[id].faction = readint(data[i]);
							break;
							//start----------//23sep2021
							case "goldcost":
							Game.techs[id].goldcost = readint(data[i]);
							break;
							case "unlimited":
							Game.techs[id].unlimited = readint(data[i]);
							break;
							case "purchaseguilink":
							Game.techs[id].purchaseguilink = readint(data[i]);
							break;
							case "temporary":
							Game.techs[id].temporary = readint(data[i]);	
							break;
							case "manacost":
							Game.techs[id].manacost = readint(data[i]);
							break;
							case "attackaction":
							Game.techs[id].attackaction = readint(data[i]);	
							break;
							case "guiactionid":
							Game.techs[id].guiactionid = readint(data[i]);
							break;
							//end------------//23sep2021
						}
						Log.i(Config.TAG,"Just Read:"+data[i].substring(0,data[i].indexOf("=")));
					}
				}
			}
		}
		catch(Exception e)
		{
			//Log.i(Config.TAG,"222:");//+e.Message);
			LocalStorage.setitem("FILE LOAD:"+file,"FAILED");//24mar2021
			Log.i(Config.TAG,"Tech Error:"+e.getMessage());
		}
	}
///////////////////Method Definition///////////////
	public static void LoadTemplates(Game game, String file)
	{
		////////////////////////
		//load all the creature/unit templates
		//that we will use in the Game.
		try
		{
			String[] data = Resources.ReadAllLines(file);
			//start-------------//7mar2021
			String[] data2 = processextraunits();
			if(data2!=null && data2.length>0)
			{
				int ii = data.length;
				data = (String[])ArrayResize.Resize(data,data.length + data2.length); //11apr2021
				for(int i=0;i<data2.length;i++)
				{
					data[ii + i] = data2[i];
				}
			}
			//end---------------//7mar2021
			int count = 0;
			for(int i=0;i<data.length;i++)
			{
				//Unit Template.....
				if(data[i].indexOf("=")>0)
				{
					switch(data[i].substring(0,data[i].indexOf("=")))
					{
						case "newtemplate":
						count++;
						break;							
					}
				}
			}
			if(count>0)
			{
				Game.templates = new Unit[count];
				int id = -1;
				int cw = 0;
				int ch = 0;
				int nw = 0;
				int nh = 0;
				for(int i=0;i<data.length;i++)
				{
					//Unit Template.....
					if(data[i].indexOf("=")>0)
					{
						switch(data[i].substring(0,data[i].indexOf("=")))
						{
							case "newtemplate":
							id++;
							Game.NOLOAD = 0;
							Game.templates[id] = new Unit(game);
							Game.templates[id].reset(game,id);
							Game.templates[id].name = readstring(data[i]);
							Game.templates[id].description = readstring(data[i]).split("\\|");
							Game.templates[id].charactername = "";//10sep2021 default it to blank to start with....
							Game.templates[id].displaycharactername = 0;//10sep2021
							count++;
							break;	
							case "noload":
							Game.templates[id].noload = readint(data[i]);	
							break;
							//start--------------//13mar2021
							case "displayname":
							Game.templates[id].displayname = readstring(data[i]);
							//start-----------------//20mar2021
							if(Game.templates[id].description[0].equals(Game.templates[id].name))
							{
								Game.templates[id].description[0] = readstring(data[i]);
							}
							//end-------------------//20mar2021
							break;
							//end----------------//13mar2021
							case "faction":
							Game.templates[id].faction = readint(data[i]);
							break;
							case "cellwidth":
							cw = readint(data[i]);
							Game.templates[id].cw = cw;
							break;
							case "cellheight":
							ch = readint(data[i]);
							Game.templates[id].ch = ch;
							break;
							case "frameswide":
							nw = readint(data[i]);
							break;
							case "frameshigh":
							nh = readint(data[i]);
							break;
							//9apr2021 hires stuff
							case "hires":
							if(Config.hires==0) //can switch it off if we wish....
							{
								continue;
							}
							boolean found = false;
							/*22sep2021
							Game.templates[id].cathiresfile = readstring(data[i]);
							
							for(int j=0;j<id;j++)
							{
								if(Game.templates[j].cathiresfile.equals(Game.templates[id].cathiresfile))
								{
									found = true;
									Game.templates[id].cathires = Game.templates[j].cathires;
									break;
								}
							}
							if(!found)
							{
								//9apr2021 observe - double the resolution, otherwise the same....
								//"hires=filename" should appear in the txt file immediately following the original 'image=' line....
								Game.templates[id].cathires = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw * 2,ch * 2,nw,nh);
								if(Game.templates[id].mirrorleftright)
								{
									Resources.FlipImage(id,Game.templates[id].cathires);
								}
							}
							*/
							break;
							case "image":
							Game.templates[id].catfile = readstring(data[i]);
							found = false;
							for(int j=0;j<id;j++)
							{
								if(Game.templates[j].catfile.equals(Game.templates[id].catfile))
								{
									found = true;
									Game.templates[id].cat = Game.templates[j].cat;
									break;
								}
							}
							if(!found)
							{
								if(Game.templates[id].noload==1)
								{
									Game.NOLOAD = 1;
								}
								Game.templates[id].cat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
								if(Game.templates[id].mirrorleftright)
								{
									if(Game.NOLOAD == 0)
									{
										Resources.FlipImage(id,Game.templates[id].cat);
									}
								}
								Game.templates[id].offxa = new int[nw*nh]; //20apr2021
								Game.templates[id].offya = new int[nw*nh]; //20apr2021
								Game.NOLOAD = 0;
							}
							break;
							case "enemyimage":
							Game.templates[id].ecatfile = readstring(data[i]);
							found = false;
							for(int j=0;j<id;j++)
							{
								if(Game.templates[j].ecatfile.equals(Game.templates[id].ecatfile))
								{
									found = true;
									Game.templates[id].ecat = Game.templates[j].ecat;
									break;
								}
							}
							if(!found)
							{
								Game.templates[id].ecat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
							}
							break;
							case "friendlyimage":
							Game.templates[id].fcatfile = readstring(data[i]);
							found = false;
							for(int j=0;j<id;j++)
							{
								if(Game.templates[j].fcatfile.equals(Game.templates[id].fcatfile))
								{
									found = true;
									Game.templates[id].fcat = Game.templates[j].fcat;
									break;
								}
							}
							if(!found)
							{
								Game.templates[id].fcat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
							}
							break;
							case "controlpoint":
							Game.templates[id].controlpoint = readint(data[i]);
							break;
							case "framesperdirn":
							Game.templates[id].framesperdirn = readint(data[i]);
							break;
							case "nodirn":
							Game.templates[id].nodirn = readint(data[i]);
							break;
							case "offy":
							Game.templates[id].offy = readint(data[i]);
							break;
							case "controlmode"://24sep2021
							Game.templates[id].controlmode = readstring(data[i]);
							break;
							case "mirror":
							if(readint(data[i])==1)
							{
								Game.templates[id].mirrorleftright = true;
							}
							break;
							case "description":
							Game.templates[id].description = readstring(data[i]).split("\\|");
							break;
							//start----------------//23sep2021
							case "basemana":
								Game.templates[id].basemana = readint(data[i]);
								Game.templates[id].mana = readint(data[i]);
							break;
							case "manarate":
								Game.templates[id].manarate = readint(data[i]);
							break;
							//end------------------//23sep2021
							case "basehp":
							//Game.templates[id].basehp = readint(data[i]);//20mar2021
							Game.templates[id].basehp = readint(data[i]) * Config.HEALTHPCT / 100;//20mar2021
							//round to the nearest 5 points
							Game.templates[id].basehp += (5 - (Game.templates[id].basehp % 5)) * Functions.sign(Game.templates[id].basehp % 5);//20mar2021
							Game.templates[id].hp = Game.templates[id].basehp;
							break;
							case "gold"://23sep2021
							Game.templates[id].gold = readint(data[i]);//23sep2021	
							break;
							case "item"://29sep2021
							Game.templates[id].itemtype = readint(data[i]);//29sep2021
							break;
							case "canpickup"://23sep2021
							Game.templates[id].canpickup = readint(data[i]);//23sep2021	
							break;
							case "armour":
							//Game.templates[id].armour = readint(data[i]); //20mar2021
							Game.templates[id].armour = readint(data[i]) * Config.ARMOURPCT / 100;//20mar2021
							break;
							case "damage":
							//Game.templates[id].damage = readint(data[i]);//20mar2021
							Game.templates[id].damage = readint(data[i]) * Config.ATTACKPCT / 100;//20mar2021
							break;
							//start--------------//2sep2021
							case "guilinkid":
							Game.templates[id].techguilinkid = readint(data[i]);
							break;
							case "researchneeded":
							Game.templates[id].unresearchedbydefault = readint(data[i]);
							break;
							//end----------------//2sep2021
							case "firebullet":
							Game.templates[id].firebullet = readint(data[i]);
							break;
							case "range":
							Game.templates[id].firerange = readint(data[i]);
							break;
							case "needlos"://15sep2021
							Game.templates[id].needlos = readint(data[i]);
							break;
							case "damage2":
							//Game.templates[id].damage2 = readint(data[i]);//20mar2021
							Game.templates[id].damage2 = readint(data[i]) * Config.ATTACKPCT / 100;//20mar2021
							break;
							case "range2":
							Game.templates[id].firerange2 = readint(data[i]);
							break;
							case "splash"://2sep2021
							Game.templates[id].splash = readint(data[i]);
							break;
							case "levelxp":
							Game.templates[id].levelxp = readint(data[i]);
							break;
							case "xpvalue":
							Game.templates[id].xpvalue = readint(data[i]);
							break;
							case "prefermobiletargets"://18sep2021
							Game.templates[id].prefermobiletargets = readint(data[i]);
							break;
							case "spellcaster":
							Game.templates[id].spellcaster = readint(data[i]);
							break;
							case "notabuffer": //15apr2021
							Game.templates[id].notabuffer = readint(data[i]);
							break;
							case "extragibbet"://18sep2021
							Game.templates[id].extragibbet = readint(data[i]);
							break;
							case "attacklimit"://23sep2021
							Game.templates[id].guiattackdisplaylimit = readint(data[i]);
							break;
							case "firespell":
							Game.templates[id].firespell = readint(data[i]);
							break;
							case "points"://17sep2021
							Game.templates[id].points = readint(data[i]);
							break;
							case "powerspell":
							Game.templates[id].powerspell = readint(data[i]);
							break;
							case "healer":
							Game.templates[id].healer = readint(data[i]);
							break;
							case "zombiemaster":
							Game.templates[id].zombiemaster = readint(data[i]);
							break;
							case "banishment": //12mar2021
							Game.templates[id].banish = readint(data[i]);
							break;
							case "dustcloud":
							Game.templates[id].dustcloud = readint(data[i]);
							break;
							case "dodge"://21oct2021
							Game.templates[id].dodge = readint(data[i]);
							break;
							case "timid":
							Game.templates[id].timid = readint(data[i]);
							break;
							case "hasleader"://21oct2021
							Game.templates[id].hasleader = readint(data[i]);
							break;
							case "hitandrun":
							Game.templates[id].hitandrun = readint(data[i]);
							break;
							case "buildpenalty": //20mar2021
							Game.templates[id].buildpenalty = readint(data[i]);//20mar2021
							break;//20mar2021
							case "brave":
							Game.templates[id].brave = readint(data[i]);
							break;
							//start-----------//01apr2021
							case "spellability":
							Game.templates[id].spellability = readint(data[i]);
							break;
							case "ping"://16sep2021
							Game.templates[id].ping = readint(data[i]);
							break;
							case "spelldefense": //magic resistance....
							Game.templates[id].spelldefense = readint(data[i]);
							break;
							//start--------------//4may2021
							case "canfly":
							Game.templates[id].canfly = readint(data[i]);
							break;
							case "canflyandwalk":
							Game.templates[id].canflyandwalk = readint(data[i]);
							break;
							case "canattackair":
							Game.templates[id].canattackair = readint(data[i]);
							break;
							//end----------------//4may2021
							//start--------------//3may2021
							case "magicrelease": //for getting out of transports
							Game.templates[id].magicrelease = readint(data[i]);
							if(Game.templates[id].magicrelease>0)
							{
								Game.templates[id].magicrelease = Unit.MAGICRELEASE;
							}
							break;
							case "magictransform": //for transforming into a different unit
							Game.templates[id].magictransform = readint(data[i]);
							if(Game.templates[id].magictransform>0)
							{
								Game.templates[id].magictransform = Unit.MAGICTRANSFORM;
							}
							break;
							case "transforminto":
							Game.templates[id].transforminto = readstring(data[i]);
							break;
							case "transformrequires":
							Game.templates[id].transformrequires = readstring(data[i]); //pipe separated list of entries....
							//currently we don't have any requirements...
							break;
							case "transportcapacity":
							Game.templates[id].transportcapacity = readint(data[i]);
							if(Game.templates[id].transportcapacity>0)
							{
								Game.templates[id].transportarray = new int[Game.templates[id].transportcapacity];
							}
							break;
							case "transportsize":
							Game.templates[id].transportsize = readint(data[i]);
							break;
							//end----------------//3may2021
							//start--------------//9apr2021
							case "magicsummoner":
							Game.templates[id].magiczombiemaster = readint(data[i]);
							if(Game.templates[id].magiczombiemaster>0)
							{
								Game.templates[id].magiczombiemaster = Unit.MAGICZOMBIEMASTER;
							}
							break;
							case "magiczombiemaster"://redundant version alias
							Game.templates[id].magiczombiemaster = readint(data[i]);
							if(Game.templates[id].magiczombiemaster>0)
							{
								Game.templates[id].magiczombiemaster = Unit.MAGICZOMBIEMASTER;
							}
							break;
							case "magicleader":
							Game.templates[id].magicleader = readint(data[i]);
							if(Game.templates[id].magicleader>0)
							{
								Game.templates[id].magicleader = Unit.MAGICLEADER;
							}
							break;
							//end----------------//9apr2021
							case "magicfrenzy":
							Game.templates[id].magicfrenzy = readint(data[i]);
							if(Game.templates[id].magicfrenzy>0)
							{
								Game.templates[id].magicfrenzy = Unit.MAGICFRENZY;
							}
							break;
							case "magicdoom":
							Game.templates[id].magicdoom = readint(data[i]);
							if(Game.templates[id].magicdoom>0)
							{
								Game.templates[id].magicdoom = Unit.MAGICDOOM;
							}
							break;
							case "magicdefense":
							Game.templates[id].magicdef = readint(data[i]);
							if(Game.templates[id].magicdef>0)
							{
								Game.templates[id].magicdef = Unit.MAGICDEF;
							}
							break;
							case "magicdef": //redundancy
							Game.templates[id].magicdef = readint(data[i]);
							if(Game.templates[id].magicdef>0)
							{
								Game.templates[id].magicdef = Unit.MAGICDEF;
							}
							break;
							//end-------------//01apr2021
							//start---------------//28mar2021
							case "magicweb":
							Game.templates[id].magicweb = readint(data[i]);
							if(Game.templates[id].magicweb>0)
							{
								Game.templates[id].magicweb = Unit.MAGICWEB;
							}
							break;
							case "magicgas":
							Game.templates[id].magicgas = readint(data[i]);
							if(Game.templates[id].magicgas>0)
							{
								Game.templates[id].magicgas = Unit.MAGICGAS;
							}
							break;
							case "magichaste":
							Game.templates[id].magichaste = readint(data[i]);
							if(Game.templates[id].magichaste>0)
							{
								Game.templates[id].magichaste = Unit.MAGICHASTE;
							}
							break;
							case "magicfear":
							Game.templates[id].magicfear = readint(data[i]);
							if(Game.templates[id].magicfear>0)
							{
								Game.templates[id].magicfear = Unit.MAGICFEAR;
							}
							break;
							case "magicshield":
							Game.templates[id].magicshield = readint(data[i]);
							if(Game.templates[id].magicshield>0)
							{
								Game.templates[id].magicshield = Unit.MAGICSHIELD;
							}
							break;
							case "magicstorm":
							Game.templates[id].magicstorm = readint(data[i]);
							if(Game.templates[id].magicstorm>0)
							{
								Game.templates[id].magicstorm = Unit.MAGICSTORM;
							}
							break;
							case "magicsword":
							Game.templates[id].magicsword = readint(data[i]);
							if(Game.templates[id].magicsword>0)
							{
								Game.templates[id].magicsword = Unit.MAGICSWORD;
							}
							break;
							case "magicstealth":
							Game.templates[id].magicstealth = readint(data[i]);
							if(Game.templates[id].magicstealth>0)
							{
								Game.templates[id].magicstealth = Unit.MAGICSTEALTH;
							}
							break;
							case "magicplant":
							Game.templates[id].magicplant = readint(data[i]);
							if(Game.templates[id].magicplant>0)
							{
								Game.templates[id].magicplant = Unit.MAGICPLANT;
							}
							break;
							case "magicwind":
							Game.templates[id].magicwind = readint(data[i]);
							if(Game.templates[id].magicwind>0)
							{
								Game.templates[id].magicwind = Unit.MAGICWIND;
							}
							break;
							//end-----------------//28mar2021
							case "highfirerate": //25Feb2021
							Game.templates[id].highfirerate = readint(data[i]);
							break;
							//start-------------//7mar2021
							case "mob": 
							Game.templates[id].mob = readint(data[i]);
							break;
							case "lightningdeath"://19oct2021
							Game.templates[id].lightningdeath = readint(data[i]);
							break;
							case "hatred": 
							Game.templates[id].hatred = readint(data[i]);
							break;
							case "craftsman": 
							Game.templates[id].craftsman = readint(data[i]);
							break;
							case "planar": 
							Game.templates[id].planar = readint(data[i]);
							break;
							case "slow": 
							Game.templates[id].slow = readint(data[i]);
							break;
							case "woodsman": 
							Game.templates[id].woodsman = readint(data[i]);
							break;
							case "stupid": 
							Game.templates[id].stupid = readint(data[i]);
							break;
							case "frenzy": 
							Game.templates[id].frenzy = readint(data[i]);
							break;
							//end---------------//7mar2021
							case "shocktroops":
							Game.templates[id].shock = readint(data[i]);
							break;
							case "shock": //2sep2021
							Game.templates[id].shock = readint(data[i]);//2sep2021
							break;//2sep2021
							case "stealth":
							Game.templates[id].stealth = readint(data[i]);
							break;
							case "damagex":
							Game.templates[id].damagex = readint(data[i]);
							break;
							case "fearsome":
							Game.templates[id].fearsome = readint(data[i]);
							break;
							case "scale"://25sep2021
							Game.templates[id].scale = readfloat(data[i]);
							break;
							case "leader":
							Game.templates[id].leader = readint(data[i]);
							break;
							case "bounddemon"://12jul2021
							Game.templates[id].bounddemon = readint(data[i]);
							break;
							case "spawner":
							Game.templates[id].spawner = readstring(data[i]);
							Game.templates[id].spawnerconstraint = "*";
							break;
							case "spawnerconstraint": //9sep2021
							Game.templates[id].spawnerconstraint = readstring(data[i]);
							break;
							case "spawnercount":
							Game.templates[id].spawnercount = readint(data[i]);
							break;
							case "spawnertime":
							Game.templates[id].spawnertime = readint(data[i]);
							break;
							case "bossmonster":
							Game.templates[id].bossmonster = readint(data[i]);
							break;
							case "flammable":
							Game.templates[id].flammable = readint(data[i]);
							break;
							case "regeneration":
							Game.templates[id].regeneration = readint(data[i]);
							break;
							case "zombie":
							Game.templates[id].zombie = readint(data[i]);
							break;
							case "evilfire":
							Game.templates[id].firespell = - readint(data[i]);
							break;
							case "sacrificial":
							Game.templates[id].sacrificial = readint(data[i]);
							break;
							case "cansacrifice": 
							Game.templates[id].cansacrifice = readint(data[i]);
							break;
							case "animosity":
							Game.templates[id].animosity = readint(data[i]);
							break;
							//start-----------//25Feb2021
							case "deadframestart":
							Game.templates[id].animmodedeadframestart = readint(data[i]);
							break;
							case "deadframeend":
							Game.templates[id].animmodedeadframeend = readint(data[i]);
							break;
							//end-------------//25Feb2021
							//start-------------//28Feb2021
							case "idle2framestart":
							Game.templates[id].animmodeidle2framestart = readint(data[i]);
							break;
							case "idle2frameend":
							Game.templates[id].animmodeidle2frameend = readint(data[i]);
							break;
							//end---------------//28Feb2021
							case "idleframestart":
							Game.templates[id].animmodeidleframestart = readint(data[i]);
							break;
							case "idleframeend":
							Game.templates[id].animmodeidleframeend = readint(data[i]);
							break;
							case "walkframestart":
							Game.templates[id].animmodewalkframestart = readint(data[i]);
							break;
							case "walkframeend":
							Game.templates[id].animmodewalkframeend = readint(data[i]);
							break;
							//2sep2021 bug fix
							case "flyframestart":
							Game.templates[id].animmodeflyframestart = readint(data[i]);
							break;
							case "flyframeend":
							Game.templates[id].animmodeflyframeend = readint(data[i]);
							break;
							//end 2sep2021
							case "att1framestart":
							Game.templates[id].animmodeattframestart = readint(data[i]);
							break;
							case "att1frameend":
							Game.templates[id].animmodeattframeend = readint(data[i]);
							break;
							case "att2framestart":
							Game.templates[id].animmodeatt2framestart = readint(data[i]);
							break;
							case "att2frameend":
							Game.templates[id].animmodeatt2frameend = readint(data[i]);
							break;
							case "walkspeed":
							Game.templates[id].walkspeed = readint(data[i]);
							Game.templates[id].origwalkspeed = readint(data[i]);//7oct2021
							break;
							case "animspeed":
							Game.templates[id].animspeed = readint(data[i]);
							break;
							case "targetfx":
							for(int a=0;a<Game.templates[id].targetfx.length;a++)
							{
								if(Game.templates[id].targetfx[a]==-1)
								{
									Game.templates[id].targetfx[a] = Resources.LoadAudio(game,readstring(data[i]),false);
									break;
								}
							}
							break;
							case "magicfx":
							for(int a=0;a<Game.templates[id].magicfx.length;a++)
							{
								if(Game.templates[id].magicfx[a]==-1)
								{
									Game.templates[id].magicfx[a] = Resources.LoadAudio(game,readstring(data[i]),false);
									break;
								}
							}
							break;
							case "impactfx":
							for(int a=0;a<Game.templates[id].impactfx.length;a++)
							{
								if(Game.templates[id].impactfx[a]==-1)
								{
									Game.templates[id].impactfx[a] = Resources.LoadAudio(game,readstring(data[i]),false);
									break;
								}
							}
							break;
							case "selectfx":
							for(int a=0;a<Game.templates[id].selectfx.length;a++)
							{
								if(Game.templates[id].selectfx[a]==-1)
								{
									Game.templates[id].selectfx[a] = Resources.LoadAudio(game,readstring(data[i]),false);
									break;
								}
							}
							break;
							case "ackfx":
							for(int a=0;a<Game.templates[id].ackfx.length;a++)
							{
								if(Game.templates[id].ackfx[a]==-1)
								{
									Game.templates[id].ackfx[a] = Resources.LoadAudio(game,readstring(data[i]),false);
									break;
								}
							}
							break;
							case "attackfx":
							for(int a=0;a<Game.templates[id].attackfx.length;a++)
							{
								if(Game.templates[id].attackfx[a]==-1)
								{
									Game.templates[id].attackfx[a] = Resources.LoadAudio(game,readstring(data[i]),false);
									break;
								}
							}
							break;
							case "deathfx": //28jul2021
							for(int a=0;a<Game.templates[id].deathfx.length;a++)
							{
								if(Game.templates[id].deathfx[a]==-1)
								{
									Game.templates[id].deathfx[a] = Resources.LoadAudio(game,readstring(data[i]),false);
									break;
								}
							}
							break;
							
						}
					}
				}
				//start-----------------//22mar2021
				//in the event we don't set the displayname we can always look it up in the translation table..in case we have it there...makes it easier sometimes.
				for(int i=0;i<Game.templates.length;i++)
				{
					if(Game.templates[i].displayname.equals(""))
					{
						Game.templates[i].displayname = Translation.TranslateWord(Game.templates[i].name,false);
					}
				}
				//end-------------------//22mar2021
			}
			LocalStorage.setitem("FILE LOAD:"+file,"SUCCESS");//24mar2021
		}
		catch(Exception e)
		{
			//Log.i(Config.TAG,"569:"+e.Message);
			LocalStorage.setitem("FILE LOAD:"+file,"FAILED");//24mar2021
		}
	}

///////////////////Method Definition///////////////
	public static boolean comparecustomversions()
	{
		//compare the custom usercampaign.txt file with the one in the 
		//install directory. This is so that we can make a copy in the user'sacrificial
		//local area for them to play around with
		int userversion = 0;
		int gameversion = 1;
		try
		{
			String[] datag = Resources.ReadAllLines(Config.customcampaignfile);
			for(int i=0;i<datag.length;i++)
			{
				if(datag[i].indexOf("=")>0)
				{
					switch(datag[i].substring(0,datag[i].indexOf("=")))
					{
						case "version":
						gameversion = readint(datag[i]);
						break;
					}
				}
			}
		}
		catch(Exception e)
		{
			//String msg0 = e.Message;
		}
		try
		{
			String[] datau = Resources.ReadAllLines(Config.usercampaignfile);
			for(int i=0;i<datau.length;i++)
			{
				if(datau[i].indexOf("=")>0)
				{
					switch(datau[i].substring(0,datau[i].indexOf("=")))
					{
						case "version":
						userversion = readint(datau[i]);
						break;
					}
				}
			}
		}
		catch(Exception e)
		{
//			String msg1 = e.Message;
		}
		if(userversion<gameversion)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

///////////////////Method Definition///////////////
	public static boolean custommissionvalid(Game game,String[] data2,int i) //24Feb2021
	{
		//verify if the mission loaded by LoadCampaign is a valid mission
		//checks factions and existence of units
		boolean anyplayers = false;
		int pfaction = Unit.HUMAN; //28Feb2021
		for(int j=i+1;j<data2.length;j++)
		{
			if(data2[j].indexOf("=")>0)
			{
				if(data2[j].substring(0,data2[j].indexOf("=")).equals("mission"))
				{
					break;
				}
				//start-------------//28Feb2021
				if(data2[j].substring(0,data2[j].indexOf("=")).equals("playerfaction"))
				{
					pfaction = Resources.readint(data2[j]);
				}
				//end---------------//28Feb2021
				if(data2[j].substring(0,data2[j].indexOf("=")).equals("unit"))
				{
					String[] unitlist = readstring(data2[j]).split(",");
					String unitname = unitlist[0];
					boolean found = false;
					for(int k=0;k<Game.templates.length;k++)
					{
						if(unitname.equals(Game.templates[k].name))
						{
							//if(Game.templates[k].faction==Unit.HUMAN) //28Feb2021
							if(Game.templates[k].faction==pfaction)//28Feb2021
							{
								anyplayers = true;
							}
							found = true;
							break;
						}
					}
					if(!found)
					{
						return false;
					}
				}
			}
		}
		if(!anyplayers)
		{
			return false;
		}
		return true;
	}

///////////////////Method Definition///////////////
	public static void LoadCampaign(Game game,String file)
	{
		////////////////////////
		//load the Campaign files including both custom and core campaigns.
		String errline = "";
		int toomanytrees = 0;
		int toomanyrocks = 0;
		int toomanywalls = 0;
		boolean getnewversion = comparecustomversions();
		try
		{
			String[] data = Resources.ReadAllLines(file);
			String[] data2 = new String[0];
			try
			{
				data2 = Resources.ReadAllLines(Config.usercampaignfile);
				LocalStorage.setitem("FILE LOAD:"+Config.usercampaignfile,"SUCCESS");
			}
			catch(Exception gge)
			{
				//Log.i(Config.TAG,gge.Message);
				LocalStorage.setitem("FILE LOAD:"+Config.usercampaignfile,"FAILED");
			}
			if(data2.length<=0 || getnewversion==true)
			{
				data2 = Resources.ReadAllLines(Config.customcampaignfile);	
//				try
//				/{
//					String txt = "";
					////for(int i=0;i<data2.length;i++)
					//{
//						txt+=data2[i]+Environment.NewLine;
					//}
					//Resources.WriteAllText(Config.usercampaignfile,txt);
				//}
				//catch(Exception ffe)
				//{
//					//Log.i(Config.TAG,ffe.Message);
				//}
			}
			int cw = 0;
			int ch = 0;
			int nw = 0;
			int nh = 0;
			int offy = 0;
			int countmissions = 0;
			int countcustoms = 0;
			for(int d=0;d<Map.deadcell.length;d++)
			{
				Map.deadcell[d] = -1;
			}
			for(int i=0;i<data2.length;i++)
			{
				errline = data2[i];
				if(data2[i].indexOf("=")>0)
				{
					switch(data2[i].substring(0,data2[i].indexOf("=")))
					{
						case "mission":
						//check mission valid....24Feb2021
						if(custommissionvalid(game,data2,i))//24Feb2021
						{
							countcustoms++;
							LocalStorage.setitem("CUSTOM MISSION:"+readstring(data2[i]),"SUCCESS");//24mar2021
						}
						else //17mar21
						{
							//Log.i(Config.TAG,"Error with custom map:"+readstring(data2[i]));
							//LocalStorage.WriteLog("Error with custom map:"+readstring(data2[i]));
							LocalStorage.setitem("CUSTOM MISSION:"+readstring(data2[i]),"FAIL");//24mar2021
						}
						break;
					}
				}
			}
			int id = -1;
			int countunits = 0;
			int unitid = -1;
			Game.countcustoms = countcustoms;
			////Log.i(Config.TAG,"Count Customs:"+countcustoms);
			for(int i=0;i<data.length;i++)
			{
				//Unit Template.....
				errline = data[i];
				if(data[i].indexOf("=")>0)
				{
					switch(data[i].substring(0,data[i].indexOf("=")))
					{
						case "shield": //15mar2021
							Game.shield = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "spellball"://12apr2021
							Game.spellball = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "whirlwind"://28mar2021
							Game.whirlwind = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "lightning"://28mar2021
							Game.lightning = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "holyaura"://26sep2021
							Game.holyaura = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "forceshield"://26sep2021
							Game.forceshield = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "bladebarrier"://26sep2021
							Game.bladebarrier = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "charmperson"://26sep2021
							Game.charmperson = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "whiteflag":
							Game.whiteflag = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "battleicon"://16oct2021
							Game.battleicon = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						
						//start-------------//15sep2021
						case "shadowup":
							Game.shadowup = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "shadowleft":
							Game.shadowleft = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "shadowright":
							Game.shadowright = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "shadowoffx":
							Game.shadowoffx = Resources.readint(data[i]);
						break;
						case "shadowoffy":
							Game.shadowoffy = Resources.readint(data[i]);
						break;
						//end---------------//15sep2021
						//start-----------------//21mar2021
						case "plus":
							Game.iconplus = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "minus":
							Game.iconminus = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "circles":
							//110,110,13,1 - standard
							Game.iconcircles = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						//end-------------------//21mar2021
						case "healthbar":
							Game.healthbar = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "cw":
							cw = readint(data[i]);
						break;
						case "ch":
							ch = readint(data[i]);
						break;
						case "nw":
							nw = readint(data[i]);
						break;
						case "nh":
							nh = readint(data[i]);
						break;
						case "offy":
							offy = readint(data[i]);
						break;
						case "menumusic":
							String[] tmpmenumusic = readstring(data[i]).split(",");
							if(tmpmenumusic.length==2)
							{
								String menumusicfile = tmpmenumusic[0];
								int menuduration = -1;
								menuduration = Integer.decode(tmpmenumusic[1]);
								if(menuduration!=-1)
								{
									Map.menumusicfile = menumusicfile;//25mar2021
									Map.menumusic = Resources.LoadAudio(game,menumusicfile,true);
									Map.menumusicplaying = -1;
								}
							}
						break;
						case "musictrack":
							String[] tmpmusic = readstring(data[i]).split(",");
							if(tmpmusic.length==2)
							{
								String musfile = tmpmusic[0];
								int duration = -1;
								duration = Integer.decode(tmpmusic[1]);
								if(duration!=-1)
								{
									if(Map.musictrack==null)
									{
										Map.musictrack = new int[Map.MAXMUSIC];
										Map.musicduration = new int[Map.MAXMUSIC];
										Map.musictrackfile = new String[Map.MAXMUSIC];//25mar2021
										for(int m=0;m<Map.musictrack.length;m++)
										{
											Map.musictrack[m]=-1;
											Map.musicduration[m]=-1;
											Map.musictrackfile[m]=""; //25mar2021
										}
										Map.musicplaying = -1;
										Map.musicstartframe = -1;
									}
									for(int m=0;m<Map.musictrack.length;m++)
									{
										if(Map.musictrack[m]==-1)
										{
											Map.musictrackfile[m] = musfile;//25mar2021
											Map.musictrack[m] = Resources.LoadAudio(game,musfile,true);
											if(Map.musictrack[m]!=-1)
											{
												Map.musicduration[m] = duration;
											}
											break;
										}
									}
								}
							}
						break;
						//start-------------//20oct2021
						case "hillgrass":
							Map.hillgrass = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "hilldesert":
							Map.hilldesert = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						case "hillsnow":
						Map.hillsnow = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
						break;
						//end---------------//20oct2021
						
						case "dead":
							for(int d=0;d<Map.deadcell.length;d++)
							{
								if(Map.deadcell[d]==-1)
								{
									Map.deadcell[d] = readint(data[i]);
								}
							}
						break;
						case "environment_ground":
							Map.tilecat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
							Map.tileframes = nw * nh;
							Map.grasstilecat = Map.tilecat;//7oct2021
							Map.snowtilecat = Resources.LoadAnimImage(game,"media/environment/snow.png",Game.renderer,cw,ch,nw,nh);//7oct2021
							Map.deserttilecat = Resources.LoadAnimImage(game,"media/environment/grounddesert.png",Game.renderer,cw,ch,nw,nh);//7oct2021
						break;
						case "environment_trees":
							Map.treecat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
							Map.grasstreecat = Map.treecat;//7oct2021
							Map.snowtreecat = Resources.LoadAnimImage(game,"media/environment/treessnow.png",Game.renderer,cw,ch,nw,nh);//7oct2021
							Map.deserttreecat = Resources.LoadAnimImage(game,"media/environment/treesdesert.png",Game.renderer,cw,ch,nw,nh);//7oct2021
							Map.treeframes = nw * nh;
							Map.treeoffsety = offy;
						break;
						//start--------------//2mar2021
						case "environment_decor":
							Map.decorcat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
							Map.decorframes = nw * nh;
							Map.decoroffsety = offy;
						break;
						//end----------------//2mar2021
						case "environment_rocks":
							Map.rockcat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
							Map.rockframes = nw * nh;
							Map.rockoffsety = offy;
						break;
						case "environment_walls":
							Map.wallcat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
							Map.wallframes = nw * nh;
							Map.walloffsety = offy;
						break;
						case "environment_fire":
							Map.firecat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
							Map.fireframes = nw * nh;
						break;
						case "mission":
							countmissions++;
						break;
					}
				}
			}
			if(countmissions>0 || countcustoms>0)
			{
				Game.missions = new Mission[countmissions+countcustoms];
				Game.overridemaxmission = countmissions;//13sep2021
				int countobjectives = 0;
				int objective = -1;
				for(int i=0;i<data.length;i++)
				{
					//Unit Template.....
					errline = data[i];
					if(data[i].indexOf("=")>0)
					{
						switch(data[i].substring(0,data[i].indexOf("=")))
						{
							case "mission":
							id++;
							Game.missions[id] = new Mission();
							Game.missions[id].name = readstring(data[i]);
							Game.missions[id].custom = false;
							Game.missions[id].gridw = Map.DEFAULTGRIDW;//10sep2021
							Game.missions[id].gridh = Map.DEFAULTGRIDH;//10sep2021
							toomanytrees = 0;
							toomanyrocks = 0;
							toomanywalls = 0;
							countunits = 0;
							for(int j=i+1;j<data.length;j++)
							{
								if(data[j].indexOf("=")>0)
								{
									if(data[j].substring(0,data[j].indexOf("=")).equals("unit"))
									{
										countunits++;
									}
									if(data[j].substring(0,data[j].indexOf("=")).equals("mission"))
									{
										break;
									}
									if(data[j].substring(0,data[j].indexOf("=")).equals("tutorial"))
									{
										break;
									}
									if(data[j].substring(0,data[j].indexOf("=")).equals("objective"))
									{
										countobjectives++;
									}
								}
							}
							if(countunits>0)
							{
								Game.missions[id].units = new Unit[countunits];
								unitid = -1;
							}
							if(countobjectives>0)
							{
								Game.missions[id].objectives = new String[countobjectives];
							}
							break;
							//26oct2020 start
							case "cw":
								cw = readint(data[i]);
							break;
							case "ch":
								ch = readint(data[i]);
							break;
							case "nw":
								nw = readint(data[i]);
							break;
							case "nh":
								nh = readint(data[i]);
							break;
							case "offy":
								offy = readint(data[i]);
							break;
							//start-----------------//10sep2021
							case "gridw":
							Game.missions[id].gridw = readint(data[i]);
							break;
							case "gridh":
							Game.missions[id].gridh = readint(data[i]);
							break;
							//end-------------------//10sep2021
							//1nov2020 start
							case "override_bk_red":
							Game.missions[id].overridergbbk = true;
							Game.missions[id].overridergbbk_r = readint(data[i]);
							break;
							case "override_bk_green":
							Game.missions[id].overridergbbk = true;
							Game.missions[id].overridergbbk_g = readint(data[i]);
							break;
							case "override_bk_blue":
							Game.missions[id].overridergbbk = true;
							Game.missions[id].overridergbbk_b = readint(data[i]);
							break;
							//1nov2020 end
							//start-----------//20oct2021
							case "grasshill":
								if(id>=0)
								{
									String[] tmpghill = readstring(data[i]).split(",");
									Game.missions[id].ghill = new int[tmpghill.length];
									for(int j=0;j<tmpghill.length;j++)
									{
										int tt = -1;
										//Int32.TryParse(tmpghill[j],out tt);
										tt = Integer.decode(tmpghill[j]);
										Game.missions[id].ghill[j] = tt;
									}
								}
							break;
							case "deserthill":
								if(id>=0)
								{
									String[] tmpdhill = readstring(data[i]).split(",");
									Game.missions[id].dhill = new int[tmpdhill.length];
									for(int j=0;j<tmpdhill.length;j++)
									{
										int tt = -1;
										//Int32.TryParse(tmpdhill[j],out tt);
										tt = Integer.decode(tmpdhill[j]);
										Game.missions[id].dhill[j] = tt;
									}
								}
							break;
							case "snowhill":
								if(id>=0)
								{
									String[] tmpshill = readstring(data[i]).split(",");
									Game.missions[id].shill = new int[tmpshill.length];
									for(int j=0;j<tmpshill.length;j++)
									{
										int tt = -1;
										//Int32.TryParse(tmpshill[j],out tt);
										tt = Integer.decode(tmpshill[j]);
										Game.missions[id].shill[j] = tt;
									}
								}
							break;
							//end------------//20oct2021
							
							case "override_ground":
								Game.missions[id].tilecat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
								Game.missions[id].tileframes = nw * nh;
								if(readstring(data[i]).indexOf("snow")>0)
								{
									Game.missions[id].issnow = true;
								}
								if(readstring(data[i]).indexOf("desert")>0)
								{
									Game.missions[id].isdesert = true;
								}
							break;
							//start--------------//2mar2021
							case "override_decor":
								Game.missions[id].decorcat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
								Game.missions[id].decorframes = nw * nh;
								Game.missions[id].decoroffsety = offy;
							break;
							//end----------------//2mar2021
							case "override_trees":
								Game.missions[id].treecat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
								Game.missions[id].treeframes = nw * nh;
								Game.missions[id].treeoffsety = offy;
							break;
							case "override_rocks":
								Game.missions[id].rockcat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
								Game.missions[id].rockframes = nw * nh;
								Game.missions[id].rockoffsety = offy;
							break;
							case "override_walls":
								Game.missions[id].wallcat = Resources.LoadAnimImage(game,readstring(data[i]),Game.renderer,cw,ch,nw,nh);
								Game.missions[id].wallframes = nw * nh;
								Game.missions[id].walloffsety = offy;
							break;
							//26oct2020 end
							case "nextmissionid":
								Game.missions[id].nextmissionid = readint(data[i]);
							break;
							case "debrief":
								Game.missions[id].debrief = readint(data[i]);
							break;
							case "failedmissionid":
								Game.missions[id].failedmissionid = readint(data[i]);
							break;
							case "floorpattern"://16sep2021
							Game.missions[id].floorpattern = readint(data[i]);
							break;
							case "indoor"://23sep2021
							Game.missions[id].indoor = readint(data[i]);	
							break;
							//start--------------//1mar2021
							case "nextmissionname":
								Game.missions[id].nextmissionname = readstring(data[i]);
							break;
							case "failedmissionname":
								Game.missions[id].failedmissionname = readstring(data[i]);
							break;
							//end----------------//1mar2021
							case "demo":
								Game.missions[id].demo = readint(data[i]);
							break;
							case "flavourtext"://18sep2021
								Game.missions[id].flavourtext = readstring(data[i]);
							break;
							//start-----------//26Feb2021
							case "fogoff":
								Game.missions[id].fogoff = readint(data[i]);
							break;
							case "neutralfog":
								Game.missions[id].neutralfog = readint(data[i]);
							break;
							//end-------------//26Feb2021
							//start-------------//28Feb2021
							case "playerfaction":
								Game.missions[id].playerfaction = readint(data[i]);
							break;
							case "enemyfaction":
								Game.missions[id].skirmishenemyfaction = readint(data[i]);
							break;
							case "unlocked":
								Game.missions[id].alwaysunlocked = readint(data[i]);
							break;
							//end---------------//28Feb2021
							//start--------------//1mar2021
							case "lockcorner":
								Game.missions[id].lockcorner = readint(data[i]);
							break;
							//end----------------//1mar2021
							case "corner":
								String[] tmpcorner = readstring(data[i]).split(",");
								if(tmpcorner.length==2)
								{
									Game.missions[id].cornerx = Integer.decode(tmpcorner[0]);
									Game.missions[id].cornery = Integer.decode(tmpcorner[1]);
								}
							break;
							case "seed":
								Game.missions[id].seed = readint(data[i]);
							break;
							case "skirmish":
								Game.missions[id].skirmish = readint(data[i]);
							break;
							case "description":
								if(Game.missions[id].description[0].equals(""))
								{
									Game.missions[id].description[0] = readstring(data[i]);
								}
								else
								{
									if(Game.missions[id].description[1].equals(""))
									{
										Game.missions[id].description[1] = readstring(data[i]);
									}
									else
									{
										Game.missions[id].description[2] = readstring(data[i]);
									}
								}
							break;
							case "mapgen":
								Game.missions[id].mapgen = 1;
							break;
							case "ai":
								Game.missions[id].ai = readint(data[i]);
							break;
							case "istutorial":
								Game.missions[id].istutorial = readint(data[i]);
							break;
							case "toomanytrees":
								toomanytrees=1;
							break;
							case "toomanyrocks":
								toomanyrocks=1;
							break;
							case "toomanywalls":
								toomanywalls = 1;
							break;
							//start--------------//2mar2021
							case "decor":
							if(id>=0)
							{
								String[] tmpdecor = readstring(data[i]).split(",");
								Game.missions[id].decorimage = new int[tmpdecor.length];
								for(int j=0;j<tmpdecor.length;j++)
								{
									int tt = -1;
									tt = Integer.decode(tmpdecor[j]);
									Game.missions[id].decorimage[j] = tt;
								}
							}
							break;
							//end----------------//2mar2021
							case "trees":
							if(id>=0)
							{
								String[] tmptrees = readstring(data[i]).split(",");
								Game.missions[id].treeimage = new int[tmptrees.length];
								for(int j=0;j<tmptrees.length;j++)
								{
									int tt = -1;
									tt = Integer.decode(tmptrees[j]);
									if(toomanytrees>0)
									{
										if(j % 3<2)
										{
											continue;
										}
									}
									Game.missions[id].treeimage[j] = tt;
								}
							}
							break;
							case "walls":
							if(id>=0)
							{
								String[] tmpwalls = readstring(data[i]).split(",");
								Game.missions[id].wallimage = new int[tmpwalls.length];
								for(int j=0;j<tmpwalls.length;j++)
								{
									int tt = -1;
									tt = Integer.decode(tmpwalls[j]);
									if(toomanywalls==1)
									{
										if((Functions.rand(0,1000) % 4)>0)
										{
											continue;
										}
									}
									Game.missions[id].wallimage[j] = tt;
								}
							}
							break;
							case "rocks":
							if(id>=0)
							{
								String[] tmprocks = readstring(data[i]).split(",");
								Game.missions[id].rockimage = new int[tmprocks.length];
								for(int j=0;j<tmprocks.length;j++)
								{
									int tt = -1;
									tt = Integer.decode(tmprocks[j]);
									if(toomanyrocks>0)
									{
										if(j % 3<2)
										{
											continue;
										}
									}
									Game.missions[id].rockimage[j] = tt;
								}
							}
							break;
							case "objective":
								objective++;
								Game.missions[id].objectives[objective] = readstring(data[i]);
							break;
							case "showkills":
								Game.missions[id].showkills = readint(data[i]);
							break;
							case "unit":
								String[] unitlist = readstring(data[i]).split(",");
								if(unitlist.length==3)
								{
									boolean success1 = true;
									boolean success2 = true;
									String name = unitlist[0];
									int x = 0;
									int y = 0;
									if(unitlist[1].equals("random"))
									{
										x = Functions.rand(Map.GRIDW * 35,Map.GRIDW*65);
										success1 = true;
									}
									else
									{
										x = Integer.decode(unitlist[1]);
									}
									if(unitlist[2].equals("random"))
									{
										y = Functions.rand(Map.GRIDH * 35,Map.GRIDH*65);
										success2 = true;
									}
									else
									{
										y = Integer.decode(unitlist[2]);
									}
									if(success1 && success2)
									{
										unitid++;
										Game.missions[id].units[unitid] = new Unit(game);
										Game.missions[id].units[unitid].x = x;
										Game.missions[id].units[unitid].y = y;
										Game.missions[id].units[unitid].name = name;
									}
								}
							break;
							//start--------------//10sep2021
							case "unitname"://unit name must immediately follow the unit that was just created....
							if(Game.missions[id].units!=null)
							{
								if(unitid<Game.missions[id].units.length && unitid>=0)
								{
									Game.missions[id].units[unitid].charactername = readstring(data[i]);
								}
							}
							break;
							case "displayunitname"://unit name must immediately follow the unit that was just created....
							if(Game.missions[id].units!=null)
							{
								if(unitid<Game.missions[id].units.length && unitid>=0)
								{
									Game.missions[id].units[unitid].displaycharactername = readint(data[i]);
								}
							}
							break;
							//end----------------//10sep2021
							case "trigger":
							//type,num,comparator,name,xx,yy,ww,hh
							//type == 1 Victory
							//type == 2 Defeat
							//comparator == 0 equal
							//comparator == -1 less than
							//comparator == 1 greater than
								if(id>=0)
								{
									String[] trigger = readstring(data[i]).split(",");
									if(trigger.length==8)
									{
										int typ = 0;
										int num = 0;
										int comp = 0;
										typ = Integer.decode(trigger[0]);
										num = Integer.decode(trigger[1]);
										comp = Integer.decode(trigger[2]);
										int xx = 0;
										int yy = 0;
										int ww = 0;
										int hh = 0;
										xx =Integer.decode(trigger[4]);
										yy = Integer.decode(trigger[5]);
										ww = Integer.decode(trigger[6]);
										hh = Integer.decode(trigger[7]);
										Game.missions[id].createtrigger(typ,num,comp,trigger[3].replace("^",","),xx,yy,ww,hh);
									}
								}
							break;
						}
					}
				}
				//
				//customs
				boolean validblock = true; //24Feb2021
				for(int i=0;i<data2.length;i++)
				{
					//Unit Template.....
					errline = data2[i];
					if(data2[i].indexOf("=")>0)
					{
						if((data2[i].substring(0,data2[i].indexOf("=")).equals("mission"))) //24Feb2021
						{//24Feb2021
							validblock = true;//24Feb2021
						}//24Feb2021
						if(!validblock)//24Feb2021
						{//24Feb2021
							continue;//24Feb2021
						}//24Feb2021
						switch(data2[i].substring(0,data2[i].indexOf("=")))
						{
							case "mission":
							validblock = true; //24Feb2021
							if(!custommissionvalid(game,data2,i))//24Feb2021
							{//24Feb2021
								validblock = false;
								continue;
							}//24Feb2021
							id++;
							Game.missions[id] = new Mission();
							Game.missions[id].name = readstring(data2[i]);
							Game.missions[id].custom = true;
							Game.missions[id].gridw = Map.DEFAULTGRIDW;//10sep2021
							Game.missions[id].gridh = Map.DEFAULTGRIDH;//10sep2021
							toomanytrees = 0;
							toomanyrocks = 0;
							countunits = 0;
							for(int j=i+1;j<data2.length;j++)
							{
								if(data2[j].indexOf("=")>0)
								{
									if(data2[j].substring(0,data2[j].indexOf("=")).equals("unit"))
									{
										countunits++;
									}
									if(data2[j].substring(0,data2[j].indexOf("=")).equals("mission"))
									{
										break;
									}
									if(data2[j].substring(0,data2[j].indexOf("=")).equals("tutorial"))
									{
										break;
									}
									if(data2[j].substring(0,data2[j].indexOf("=")).equals("objective"))
									{
										countobjectives++;
									}
								}
							}
							if(countunits>0)
							{
								Game.missions[id].units = new Unit[countunits];
								unitid = -1;
							}
							if(countobjectives>0)
							{
								Game.missions[id].objectives = new String[countobjectives];
							}
							break;
							//26oct2020 start
							case "cw":
								cw = readint(data2[i]);
							break;
							case "ch":
								ch = readint(data2[i]);
							break;
							case "nw":
								nw = readint(data2[i]);
							break;
							case "nh":
								nh = readint(data2[i]);
							break;
							case "offy":
								offy = readint(data2[i]);
							break;
							//start-----------------//10sep2021
							case "gridw":
							Game.missions[id].gridw = readint(data2[i]);
							break;
							case "gridh":
							Game.missions[id].gridh = readint(data2[i]);
							break;
							//end-------------------//10sep2021
							//1nov2020 start
							case "override_bk_red":
							Game.missions[id].overridergbbk = true;
							Game.missions[id].overridergbbk_r = readint(data2[i]);
							break;
							case "override_bk_green":
							Game.missions[id].overridergbbk = true;
							Game.missions[id].overridergbbk_g = readint(data2[i]);
							break;
							case "override_bk_blue":
							Game.missions[id].overridergbbk = true;
							Game.missions[id].overridergbbk_b = readint(data2[i]);
							break;
							//1nov2020 end
							case "override_ground":
								Game.missions[id].tilecat = Resources.LoadAnimImage(game,readstring(data2[i]),Game.renderer,cw,ch,nw,nh);
								Game.missions[id].tileframes = nw * nh;
								if(readstring(data2[i]).indexOf("snow")>0)
								{
									Game.missions[id].issnow = true;
								}
								if(readstring(data2[i]).indexOf("desert")>0)
								{
									Game.missions[id].isdesert = true;
								}
							break;
							case "override_trees":
								Game.missions[id].treecat = Resources.LoadAnimImage(game,readstring(data2[i]),Game.renderer,cw,ch,nw,nh);
								Game.missions[id].treeframes = nw * nh;
								Game.missions[id].treeoffsety = offy;
							break;
							//start--------------//2mar2021
							case "override_decor":
								Game.missions[id].decorcat = Resources.LoadAnimImage(game,readstring(data2[i]),Game.renderer,cw,ch,nw,nh);
								Game.missions[id].decorframes = nw * nh;
								Game.missions[id].decoroffsety = offy;
							break;
							//end----------------//2mar2021
							case "override_rocks":
								Game.missions[id].rockcat = Resources.LoadAnimImage(game,readstring(data2[i]),Game.renderer,cw,ch,nw,nh);
								Game.missions[id].rockframes = nw * nh;
								Game.missions[id].rockoffsety = offy;
							break;
							case "override_walls":
								Game.missions[id].wallcat = Resources.LoadAnimImage(game,readstring(data2[i]),Game.renderer,cw,ch,nw,nh);
								Game.missions[id].wallframes = nw * nh;
								Game.missions[id].walloffsety = offy;
							break;
							//26oct2020 end
							case "nextmissionid":
								Game.missions[id].nextmissionid = readint(data2[i]);
							break;
							case "debrief":
								Game.missions[id].debrief = readint(data2[i]);
							break;
							case "failedmissionid":
								Game.missions[id].failedmissionid = readint(data2[i]);
							break;
							//start--------------//1mar2021
							case "nextmissionname":
								Game.missions[id].nextmissionname = readstring(data2[i]);
							break;
							case "failedmissionname":
								Game.missions[id].failedmissionname = readstring(data2[i]);
							break;
							//end----------------//1mar2021
							case "demo":
								Game.missions[id].demo = 0;//readint(data2[i]);
							break;
							//start-----------//26Feb2021
							case "fogoff":
								Game.missions[id].fogoff = readint(data2[i]);
							break;
							case "neutralfog":
								Game.missions[id].neutralfog = readint(data2[i]);
							break;
							//end-------------//26Feb2021
							//start-------------//28Feb2021
							case "playerfaction":
								Game.missions[id].playerfaction = readint(data2[i]);
							break;
							case "enemyfaction":
								Game.missions[id].skirmishenemyfaction = readint(data2[i]);
							break;
							case "flavourtext"://18sep2021
								Game.missions[id].flavourtext = readstring(data2[i]);
							break;
							case "floorpattern"://16sep2021
								Game.missions[id].floorpattern = readint(data2[i]);
							break;
							case "unlocked":
								Game.missions[id].alwaysunlocked = readint(data2[i]);
							break;
							//end---------------//28Feb2021
							//start--------------//1mar2021
							case "lockcorner":
								Game.missions[id].lockcorner = readint(data2[i]);
							break;
							//end----------------//1mar2021
							case "corner":
								String[] tmpcorner = readstring(data2[i]).split(",");
								if(tmpcorner.length==2)
								{
									Game.missions[id].cornerx = Integer.decode(tmpcorner[0]);
									Game.missions[id].cornery = Integer.decode(tmpcorner[1]);
								}
							break;
							case "seed":
								Game.missions[id].seed = readint(data2[i]);
							break;
							case "skirmish":
								Game.missions[id].skirmish = readint(data2[i]);
							break;
							case "mapgen":
								Game.missions[id].mapgen = 1;
							break;
							case "indoor"://23sep2021
							Game.missions[id].indoor = readint(data2[i]);	
							break;
							case "ai":
								Game.missions[id].ai = readint(data2[i]);
							break;
							case "description":
								if(Game.missions[id].description[0].equals(""))
								{
									//Game.missions[id].description[0] = readstring(data2[i]);//21mar2021
									Game.missions[id].description[0] = Translation.TranslateWord(readstring(data2[i]),false);//21mar2021
								}
								else
								{
									if(Game.missions[id].description[1].equals(""))
									{
										//Game.missions[id].description[1] = readstring(data2[i]);//22mar2021
										Game.missions[id].description[1] = Translation.TranslateWord(readstring(data2[i]),false);//22mar2021
									}
									else
									{
										//Game.missions[id].description[2] = readstring(data2[i]);//22mar2021
										Game.missions[id].description[2] = Translation.TranslateWord(readstring(data2[i]),false);//22mar2021
									}
								}
							break;
							case "istutorial":
								Game.missions[id].istutorial = 0;//readint(data[i]);
							break;
							//start--------------//2mar2021
							case "decor":
							if(id>=0)
							{
								String[] tmpdecor = readstring(data2[i]).split(",");
								Game.missions[id].decorimage = new int[tmpdecor.length];
								for(int j=0;j<tmpdecor.length;j++)
								{
									int tt = -1;
									tt =Integer.decode(tmpdecor[j]);
									Game.missions[id].decorimage[j] = tt;
								}
							}
							break;
							//end----------------//2mar2021
							case "trees":
							if(id>=0)
							{
								String[] tmptrees = readstring(data2[i]).split(",");
								Game.missions[id].treeimage = new int[tmptrees.length];
								for(int j=0;j<tmptrees.length;j++)
								{
									int tt = -1;
									tt = Integer.decode(tmptrees[j]);
									Game.missions[id].treeimage[j] = tt;
								}
							}
							break;
							case "walls":
							if(id>=0)
							{
								String[] tmpwalls = readstring(data2[i]).split(",");
								Game.missions[id].wallimage = new int[tmpwalls.length];
								for(int j=0;j<tmpwalls.length;j++)
								{
									int tt = -1;
									tt = Integer.decode(tmpwalls[j]);
									Game.missions[id].wallimage[j] = tt;
								}
							}
							break;
							case "rocks":
							if(id>=0)
							{
								String[] tmprocks = readstring(data2[i]).split(",");
								Game.missions[id].rockimage = new int[tmprocks.length];
								for(int j=0;j<tmprocks.length;j++)
								{
									int tt = -1;
									tt = Integer.decode(tmprocks[j]);
									Game.missions[id].rockimage[j] = tt;
								}
							}
							break;
							case "objective":
								objective++;
								//Game.missions[id].objectives[objective] = readstring(data2[i]);//22mar2021
								Game.missions[id].objectives[objective] = Translation.TranslateWord(readstring(data2[i]),false);//22mar2021
							break;
							case "showkills":
								Game.missions[id].showkills = readint(data2[i]);
							break;
							case "unit":
								String[] unitlist = readstring(data2[i]).split(",");
								if(unitlist.length==3)
								{
									boolean success1 = true;
									boolean success2 = true;
									String name = unitlist[0];
									int x = 0;
									int y = 0;
									if(unitlist[1].equals("random"))
									{
										x = Functions.rand(Map.GRIDW * 35,Map.GRIDW*65);
										success1 = true;
									}
									else
									{
										x = Integer.decode(unitlist[1]);
									}
									if(unitlist[2].equals("random"))
									{
										y = Functions.rand(Map.GRIDH * 35,Map.GRIDH*65);
										success2 = true;
									}
									else
									{
										y = Integer.decode(unitlist[2]);
									}
									if(success1 && success2)
									{
										unitid++;
										Game.missions[id].units[unitid] = new Unit(game);
										Game.missions[id].units[unitid].x = x;
										Game.missions[id].units[unitid].y = y;
										Game.missions[id].units[unitid].name = name;
									}
								}
							break;
							//start--------------//10sep2021
							case "unitname"://unit name must immediately follow the unit that was just created....
							if(Game.missions[id].units!=null)
							{
								if(unitid<Game.missions[id].units.length && unitid>=0)
								{
									Game.missions[id].units[unitid].charactername = readstring(data2[i]);
								}
							}
							break;
							case "displayunitname":
							if(Game.missions[id].units!=null)
							{
								if(unitid<Game.missions[id].units.length && unitid>=0)
								{
									Game.missions[id].units[unitid].displaycharactername = readint(data2[i]);
								}
							}
							break;
							//end----------------//10sep2021
							case "trigger":
							//type,num,comparator,name,xx,yy,ww,hh
							//type == 1 Victory
							//type == 2 Defeat
							//comparator == 0 equal
							//comparator == -1 less than
							//comparator == 1 greater than
								if(id>=0)
								{
									String[] trigger = readstring(data2[i]).split(",");
									if(trigger.length==8)
									{
										int typ = 0;
										int num = 0;
										int comp = 0;
										typ = Integer.decode(trigger[0]);
										num = Integer.decode(trigger[1]);
										comp = Integer.decode(trigger[2]);
										int xx = 0;
										int yy = 0;
										int ww = 0;
										int hh = 0;
										xx = Integer.decode(trigger[4]);
										yy = Integer.decode(trigger[5]);
										ww = Integer.decode(trigger[6]);
										hh = Integer.decode(trigger[7]);
										Game.missions[id].createtrigger(typ,num,comp,trigger[3].replace("^",","),xx,yy,ww,hh);
									}
								}
							break;
						}
					}
				}
			}
			LocalStorage.setitem("FILE LOAD:"+file,"SUCCESS");//24mar2021
		}
		catch(Exception e)
		{
			//Log.i(Config.TAG,"766:"+"Error in file on line containing:"+errline+" "+e.Message);
			//LocalStorage.WriteLog("766:"+"Error in file on line containing:"+errline+" "+e.Message);
			LocalStorage.setitem("FILE LOAD:"+file,"FAILED");//24mar2021
			Log.w(Config.TAG,"Error:"+errline);
		}
	}

///////////////////Method Definition///////////////
	public static int LoadFont(Game game,String file,int ptsize)
	{
		////////////////////////
		if(Game.GUIHALFRES>1)//25sep2021
		{
			ptsize/=Game.GUIHALFRES;
			if(ptsize>4)
			{
				ptsize-=2;//just an extra notch....
			}
		}
		if(Game.LETTERBOX)
		{
			ptsize *=3;
			ptsize /=5;
		}
		//Load a font in the game for use
		Fonts f = new Fonts();
		//ptsize*=Config.FONTALIAS;
		if(!file.equals("") && file!=null)//28Feb2021
		{
			if(ptsize>=20)
			{
				//f.font = SDL_ttf.TTF_OpenFont(file,ptsize*Config.FONTALIAS);
			}
			else
			{
				//f.font = SDL_ttf.TTF_OpenFont(file,ptsize);
			}
			f.font = Typeface.createFromAsset(MainActivity.assetmgr, file); //must exist or will fail.
		}
		if(f.font==null)
		{
			//Log.i(Config.TAG,"Could Not Open Font:"+file+". Error:"+SDL.SDL_GetError());
			//Network.reporterror("FontLoadFailure:"+file,false);//15mar2021
			LocalStorage.setitem("FILE LOAD:"+file,"FAILED TO LOAD");
		}
		else
		{
			LocalStorage.setitem("FILE LOAD:"+file,"LOADED");
		}
		int i = Game.fonts.length;
		Game.fonts = (Fonts[])ArrayResize.Resize(Game.fonts,i + 1); //11apr2021

		f.file = file;//24mar2021
		Game.fonts[i] = f;
		Game.fonts[i].font = f.font;
		Game.fonts[i].ptsize = ptsize;
		i++;
		return i - 1;
	}
	//

///////////////////Method Definition///////////////
	public static int LoadAudio(Game game,String file,boolean music)
	{
		////////////////////////
		//Load an Audio file of .wav type
		for(int j=0;j<Game.audios.length;j++)
		{
			if(Game.audios[j].file.equals(file))
			{
				return j;
			}
		}
		Audios a = new Audios();
		a.loop = music;
		a.file = file; //25mar2021
		if(music)
		{
			if(!Config.STREAMLOADAUDIO)//25mar2021
			{
				if(!file.equals("") && file!=null)//28Feb2021
				{
					//a.audio = SDL_mixer.Mix_LoadMUS(file);
				}
				if(a.audio<=0)
				{
					//Log.i(Config.TAG,"Could Not Load Music:"+file+". Error:"+SDL.SDL_GetError());
					//Network.reporterror("MusicLoadFailure:"+file,false);//15mar2021
					LocalStorage.setitem("FILE LOAD:"+file,"FAILED TO LOAD"); //24mar2021
				}
				else //24mar2021
				{
					LocalStorage.setitem("FILE LOAD:"+file,"LOADED"); //24mar2021
				}
			}
			else
			{
				//do nothing yet...
			}
			a.ismusic = true;
		}
		else
		{
			if(!file.equals("") && file!=null)//28Feb2021
			{
				AssetFileDescriptor fd = null;//25sep2021
	            try
	            {
	                fd = MainActivity.assetmgr.openFd(file);
	                a.audio = Audios.sndpool.load(fd, 1);
	            }
	            catch (Exception e)
	            {
	                Log.w(Config.TAG, "Sound Effect Not Loaded");
	            }
	            try
	            {
	                fd.close();
	                fd = null;
	            }
	            catch (Exception e)
	            {
	                Log.e(Config.TAG, "Error closing file descriptor");
	            }
			}
			if(a.audio<=0)
			{
				//Log.i(Config.TAG,"Could Not Load Sound:"+file+". Error:"+SDL.SDL_GetError());
				//Network.reporterror("SoundLoadFailure:"+file,false);//15mar2021
				LocalStorage.setitem("FILE LOAD:"+file,"FAILED TO LOAD"); //24mar2021
			}
			else//24mar2021
			{
				LocalStorage.setitem("FILE LOAD:"+file,"LOADED"); //24mar2021
			}
		
		}
		int i = Game.audios.length;
		Game.audios = (Audios[])ArrayResize.Resize(Game.audios,i + 1); //11apr2021

		Game.audios[i] = a;
		Game.audios[i].index = i;
		Game.audios[i].loop = music;
		Game.audios[i].volume = 1;
		Game.audios[i].file = file;
		i++;
		return i - 1;
	}
	//
	//start-------------//28Feb2021

///////////////////Method Definition///////////////
	public static void StreamImage(Game game,int i)
	{
		////////////////////////
		//not used
		//used after an image is released...and we want to reload it in Game....in a separate thread.
		if(i>=0 && i<Game.images.length)
		{
			if(Game.images[i].loaded==false && Game.images[i].stream==false)
			{
				if(Game.images[i].texture==null)
				{
					Game.images[i].stream = true;
				}
			}
		}
	}

///////////////////Method Definition///////////////
	public static boolean FreeImage(Game game,int i)
	{
		////////////////////////
		//frees images from memory
		if(i>=0 && i<Game.images.length)
		{
			if(Game.images[i].texture!=null && Game.images[i].loaded==true)
			{
				LocalStorage.setitem("FREE IMAGE:"+Game.images[i].file,"FAILED"); //24mar2021
				//SDL.SDL_DestroyTexture(Game.images[i].texture);
				LocalStorage.setitem("FREE IMAGE:"+Game.images[i].file,"SUCCESS"); //24mar2021
				Game.images[i].loaded = false;
				Game.images[i].texture = null;
				return true;
			}
		}
		return false;
	}
	//end---------------//28Feb2021
	//

///////////////////Method Definition///////////////
	public static int LoadImage(Game game,String file,int renderer,int w,int h) //note the slight change.....added w and h as can't work out how to do it otherwise....
	{
		////////////////////////
		//Load an image of the form .png or .jpg into memory
		boolean loaded = false;//28Feb2021
		for(int j=0;j<Game.images.length;j++)//26oct2020
		{
			if(Game.images[j].file.equals(file))
			{
				//start-------------//28Feb2021
				if(Game.images[j].loaded==false) //assumes the image was loaded once before successfully, cleared out and needs to be loaded again.....
				{
					//Game.images[j].texture = SDL_image.IMG_LoadTexture(renderer,file);
					BitmapFactory.Options opts = new BitmapFactory.Options();
					opts.inScaled = false;
					Game.images[j].texture = LoadBitmap(file,opts);//BitmapFactory.decodeFile(file, opts);
					if(Game.images[j].texture==null)
					{
						//Log.i(Config.TAG,"Could Not Load Texture:"+file+". Error:"+SDL.SDL_GetError());
						//Network.reporterror("TextureLoadFailure:"+file,false);//15mar2021
						LocalStorage.setitem("FILE LOAD:"+file,"FAILED TO LOAD");//24mar2021
					}
					else
					{
						Game.images[j].loaded = true;
						LocalStorage.setitem("FILE LOAD:"+file,"LOADED"); //24mar2021
					}
				}
				//end---------------//28Feb2021
				return j;
			}
		}
		Images img = new Images();
		if(!Config.STREAMLOAD) //28Feb2021
		{
			if(!file.equals("") && file!=null)//28Feb2021
			{
				//img.texture = SDL_image.IMG_LoadTexture(renderer,file);
				BitmapFactory.Options opts = new BitmapFactory.Options();
				opts.inScaled = false;
				img.texture = LoadBitmap(file,opts);//BitmapFactory.decodeFile(file, opts);
				
			}
			if(img.texture==null)
			{
				//Log.i(Config.TAG,"Could Not Load Texture:"+file+". Error:"+SDL.SDL_GetError());
				//Network.reporterror("TextureLoadFailure:"+file,false);//15mar2021
				LocalStorage.setitem("FILE LOAD:"+file,"FAILED TO LOAD");//24mar2021
			}
			else
			{
				loaded = true;
				LocalStorage.setitem("FILE LOAD:"+file,"LOADED");//24mar2021
			}
		}
		int i = Game.images.length;
		Game.images = (Images[])ArrayResize.Resize(Game.images,i + 1); //11apr2021
		Game.images[i] = img;
		Game.images[i].file = file;//26oct2020
		Game.images[i].texture = img.texture;
		Game.images[i].anim = false;
		Game.images[i].index = i;
		Game.images[i].cwx = w;//??
		Game.images[i].chy = h;//??
		Game.images[i].chn = 1;
		Game.images[i].cwn = 1;
		Game.images[i].stream = Config.STREAMLOAD;//28Feb2021
		Game.images[i].loaded = loaded; ///28Feb2021
		Game.images[i].okloaded = loaded; //28Feb2021
		Game.images[i].neverloaded = !loaded; //28Feb2021
		i++;
		return i - 1;
	}
	//

///////////////////Method Definition///////////////
	public static Bitmap SpecialFlip(Bitmap bmp)
	{
		Matrix m = new Matrix();
		m.postScale(-1, 1,35,42);
		Bitmap src = bmp;
		Bitmap dst = Bitmap.createBitmap(src.getWidth(), (src.getHeight() * 8)/5, Bitmap.Config.ARGB_8888);
		Paint p = new Paint();
		int frames = 18 * 5;
		frames = (frames * 8)/5;
		int framesperdirn = 18;
		int x = 0;
		int y = 0;
		int count = 0;
		Canvas cdst = new Canvas(dst);
		Rect r1 = new Rect();
		Rect r2 = new Rect();
		for(int i=0;i<frames;i++)
		{
			if(count<5)
			{
				r1.left = x * 70;
				r1.top = y * 85;
				r1.bottom = r1.top + 85;
				r1.right = r1.left + 70;
				cdst.drawBitmap(src,r1 ,r1 , p);
			}
			else
			{
				r1.left = x * 70;
				r1.top = (8 - count) * 85;
				r1.bottom = r1.top + 85;
				r1.right = r1.left + 70;
				r2.left = 0;
				r2.top = 0;
				r2.bottom = 85;
				r2.right = 70;
				Bitmap frame = Bitmap.createBitmap(70,85,Bitmap.Config.ARGB_8888);
				Canvas cfrm = new Canvas(frame);
				cfrm.drawARGB(0, 0, 0, 0);
				cfrm.drawBitmap(src,r1 ,r2 , p);
				Bitmap frame2 = Bitmap.createBitmap(70,85,Bitmap.Config.ARGB_8888);
				Canvas cfrm2 = new Canvas(frame2);
				cfrm2.drawBitmap(frame, m, p);
				r1.top = y * 85;
				r1.bottom = r1.top + 85;
				cdst.drawBitmap(frame2, r2, r1,p);
				frame.recycle();
				frame = null;
				frame2.recycle();
				frame2 = null;
			}
			x+=1;
			if((i + 1) % framesperdirn==0)
			{
				y+=1;
				x=0;
				count++;
			}
		}
		src.recycle();
		src = null;
		return dst;

	}
///////////////////Method Definition///////////////
	public static void FlipImage(int tid,int cat)
	{
		
		//while debugging....
		Game.LOWONMEMORY = 0;
		if(Game.templates[tid].framesperdirn<=0)
		{
			return;
		}
		if(cat>=0 && cat<Game.images.length)
		{	
			if(Game.images[cat].texture!=null)
			{
				Matrix m = new Matrix();
				m.postScale(-1, 1,Game.images[cat].cwx/2,Game.images[cat].chy/2);
				Bitmap src = Game.images[cat].texture;
				boolean started = false;
				int count = 0;
				Log.i(Config.TAG,"Flipping Image:"+Game.images[cat].file);
				while(!started && count<4)
				{
					started = false;
					count++;
					final Runtime runtime = Runtime.getRuntime();
					final long usedMeminMB = (runtime.totalMemory() - runtime.freeMemory()) / 1048576L;
					final long maxHeapSizeinMB = runtime.maxMemory() / 1048576L;
					final long availmem = maxHeapSizeinMB - usedMeminMB;
					final long memneeded = (src.getWidth() * src.getHeight() * 2 * 4) / 1048576L;
					if(memneeded>(availmem*3)/6)
					{
						Log.w(Config.TAG,"Low on  memory:Flipping Image");
						
						Game.LOWONMEMORY = 0;//removed
						System.gc();
						try 
						{
							Thread.sleep(500);
						}
						catch (InterruptedException e) 
						{
							e.printStackTrace();
						}
					}
					else
					{
						started = true;
					}
				}
				Bitmap dst = Bitmap.createBitmap((Game.images[cat].cwn * Game.images[cat].cwx), (((Game.images[cat].chn * Game.images[cat].chy) * 8)/5), Bitmap.Config.ARGB_8888);
				Paint p = new Paint();
				int frames = Game.images[cat].cwn * Game.images[cat].chn;
				frames = (frames * 8)/5;
				int framesperdirn = Game.templates[tid].framesperdirn;
				int x = 0;
				int y = 0;
				count = 0;
				Canvas cdst = new Canvas(dst);
				Rect r1 = new Rect();
				Rect r2 = new Rect();
				for(int i=0;i<frames;i++)
				{
					if(count<5)
					{
						r1.left = x * Game.images[cat].cwx;
						r1.top = y * Game.images[cat].chy;
						r1.bottom = r1.top + Game.images[cat].chy;
						r1.right = r1.left + Game.images[cat].cwx;
						cdst.drawBitmap(src,r1 ,r1 , p);
					}
					else
					{
						r1.left = x * Game.images[cat].cwx;
						r1.top = (8 - count) * Game.images[cat].chy;
						r1.bottom = r1.top + Game.images[cat].chy;
						r1.right = r1.left + Game.images[cat].cwx;
						r2.left = 0;
						r2.top = 0;
						r2.bottom = Game.images[cat].chy;
						r2.right = Game.images[cat].cwx;
						Bitmap frame = Bitmap.createBitmap(Game.images[cat].cwx,Game.images[cat].chy,Bitmap.Config.ARGB_8888);
						Canvas cfrm = new Canvas(frame);
						cfrm.drawARGB(0, 0, 0, 0);
						cfrm.drawBitmap(src,r1 ,r2 , p);
						Bitmap frame2 = Bitmap.createBitmap(Game.images[cat].cwx,Game.images[cat].chy,Bitmap.Config.ARGB_8888);
						Canvas cfrm2 = new Canvas(frame2);
						cfrm2.drawBitmap(frame, m, p);
						r1.top = y * Game.images[cat].chy;
						r1.bottom = r1.top + Game.images[cat].chy;
						cdst.drawBitmap(frame2, r2, r1,p);
						frame.recycle();
						frame = null;
						frame2.recycle();
						frame2 = null;
					}
					x+=1;
					if((i + 1) % framesperdirn==0)
					{
						y+=1;
						x=0;
						count++;
					}
				}
				src.recycle();
				src = null;
				Game.images[cat].texture = dst;
				Game.images[cat].chn = 8;
				Game.templates[tid].mirrorleftright = false;
			}
		}
	}
///////////////////Method Definition///////////////
	public static int LoadAnimImage(Game game,String file,int renderer,int cellwidth, int cellheight, int cellswide, int cellshigh)
	{
		////////////////////////
		//Load an animated image of the form .png or .jpg into memory
		boolean loaded = false; //28Feb2021
		for(int j=0;j<Game.images.length;j++)//26oct2020
		{
			if(Game.images[j].file.equals(file))
			{
				//start-------------//28Feb2021
				if(Game.images[j].loaded==false) //assumes the image was loaded once before successfully, cleared out and needs to be loaded again.....
				{
				//	Game.images[j].texture = SDL_image.IMG_LoadTexture(renderer,file);
					BitmapFactory.Options opts = new BitmapFactory.Options();
					opts.inScaled = false;
					Game.images[j].texture = LoadBitmap(file,opts);//BitmapFactory.decodeFile(file, opts);
					if(Game.images[j].texture==null)
					{
						//Log.i(Config.TAG,"Could Not Load Texture:"+file+". Error:"+SDL.SDL_GetError());
						//Network.reporterror("TextureLoadFailure:"+file,false);//15mar2021
						LocalStorage.setitem("FILE LOAD:"+file,"FAILED TO LOAD");//24mar2021
					}
					else
					{
						Game.images[j].loaded = true;
						//Game.images[j].beingrecycled = false;
						LocalStorage.setitem("FILE LOAD:"+file,"LOADED");//24mar2021
					}
				}
				//end---------------//28Feb2021
				return j;
			}
		}
		Images img = new Images();
		if(!Config.STREAMLOAD) //28Feb2021
		{
			if(!file.equals("") && file!=null) //28Feb2021
			{
				//img.texture = SDL_image.IMG_LoadTexture(renderer,file);
				if(Game.NOLOAD==0)
				{
					BitmapFactory.Options opts = new BitmapFactory.Options();
					opts.inScaled = false;
					img.texture = LoadBitmap(file,opts);//BitmapFactory.decodeFile(file, opts);
				}
				else
				{
					img.texture = null;
				}
				
			}
			if(img.texture==null)
			{
				if(Game.NOLOAD==0)
				{
					Log.i(Config.TAG,"Could Not Load Texture:"+file);
				//	Network.reporterror("TextureLoadFailure:"+file,false);//15mar2021
					LocalStorage.setitem("FILE LOAD:"+file,"FAILED TO LOAD");//24mar2021
				}
				
			}
			else
			{
				loaded = true;
				LocalStorage.setitem("FILE LOAD:"+file,"LOADED");//24mar2021
				Log.i(Config.TAG,"Texture Loaded:"+file);
				//img.beingrecycled = false;
			}
		}
		int i = Game.images.length;
		Game.images = (Images[])ArrayResize.Resize(Game.images,i + 1); //11apr2021
		Game.images[i] = img;
		Game.images[i].file = file;//26oct2020
		Game.images[i].texture = img.texture;
		Game.images[i].anim = true;
		Game.images[i].index = i;
		Game.images[i].cwx = cellwidth;
		Game.images[i].chy = cellheight;
		Game.images[i].chn = cellshigh;
		Game.images[i].cwn = cellswide;
		Game.images[i].stream = Config.STREAMLOAD;//28Feb2021
		Game.images[i].loaded = loaded;//28Feb2021
		Game.images[i].okloaded = loaded; //28Feb2021
		Game.images[i].neverloaded = !loaded; //28Feb2021
		i++;
		return i - 1;
	}
	
	public static void LoadNewArmy(final String oldarmy1,final String newarmy1,final String oldarmy2, final String newarmy2)
	{
		//unload out of memory the old bitmaps....
		if(THREADRUNNING==1)
		{
			return;
		}
		THREADRUNNING = 1;
		for(int i=0;i<Game.templates.length;i++)
		{
			Game.images[Game.templates[i].cat].beingrecycled = true;
		}
		new Thread(new Runnable()
		{
			@Override
			public void run() 
			{
				//unload old bitmaps from old army.....
				for(int i=0;i<Game.templates.length;i++)
				{
					//if(Game.templates[i].name.indexOf(oldarmy1)>=0)
					//{
					UnLoadBitmap(Game.templates[i].catfile);
					//}
				}
				//for(int i=0;i<Game.templates.length;i++)
				//{
//					if(Game.templates[i].name.indexOf(oldarmy2)>=0)
					//{
//						UnLoadBitmap(Game.templates[i].catfile);
					//}
				//}
				Game.NOLOAD = 0;
				for(int i=0;i<Game.templates.length;i++)
				{
					if(Game.templates[i].name.indexOf(newarmy1)>=0)
					{
						Game.templates[i].noload = 0;
						Game.templates[i].cat = Resources.LoadAnimImage(null,Game.templates[i].catfile,Game.renderer,Game.templates[i].cw,Game.templates[i].ch,Game.templates[i].framesperdirn,5);
						Resources.FlipImage(i,Game.templates[i].cat);
						Game.images[Game.templates[i].cat].beingrecycled = false;
					}
				}
				Game.NOLOAD = 0;
				for(int i=0;i<Game.templates.length;i++)
				{
					if(Game.templates[i].name.indexOf(newarmy2)>=0)
					{
						Game.templates[i].noload = 0;
						Game.templates[i].cat = Resources.LoadAnimImage(null,Game.templates[i].catfile,Game.renderer,Game.templates[i].cw,Game.templates[i].ch,Game.templates[i].framesperdirn,5);
						Resources.FlipImage(i,Game.templates[i].cat);
						Game.images[Game.templates[i].cat].beingrecycled = false;
					}
				}
				THREADRUNNING = 0;
			}
		}).start();
	}
	
	public static void LoadNewArmy(final String oldarmy,final String newarmy)
	{
		//unload out of memory the old bitmaps....
		if(THREADRUNNING==1)
		{
			return;
		}
		THREADRUNNING = 1;
		for(int i=0;i<Game.templates.length;i++)
		{
			if(Game.templates[i].name.indexOf(oldarmy)>=0)
			{
				Game.images[Game.templates[i].cat].beingrecycled = true;
			}
			if(Game.templates[i].name.indexOf(newarmy)>=0)
			{
				Game.images[Game.templates[i].cat].beingrecycled = true;
			}
		}
		new Thread(new Runnable()
		{
			@Override
			public void run() 
			{
				//unload old bitmaps from old army.....
				for(int i=0;i<Game.templates.length;i++)
				{
					if(Game.templates[i].name.indexOf(oldarmy)>=0)
					{
						UnLoadBitmap(Game.templates[i].catfile);
					}
				}
				Game.NOLOAD = 0;
				for(int i=0;i<Game.templates.length;i++)
				{
					if(Game.templates[i].name.indexOf(newarmy)>=0)
					{
						Game.templates[i].noload = 0;
						Game.templates[i].cat = Resources.LoadAnimImage(null,Game.templates[i].catfile,Game.renderer,Game.templates[i].cw,Game.templates[i].ch,Game.templates[i].framesperdirn,5);
						Resources.FlipImage(i,Game.templates[i].cat);
						Game.images[Game.templates[i].cat].beingrecycled = false;
					}
				}
				THREADRUNNING = 0;
			}
		}).start();
	}
	
	public static void UnLoadBitmap(String file)
	{
		for(int i=0;i<Game.images.length;i++)
		{
			if(Game.images[i].file!=null)
			{
				if(Game.images[i].file.equals(file))
				{
					if(Game.images[i].texture!=null)
					{
						Game.images[i].texture.recycle();
						Game.images[i].texture = null;
						Game.images[i].loaded = false;
					}
				}
			}
		}
	}
	
	public static Bitmap LoadBitmap(String file,BitmapFactory.Options opts)
	{
		InputStream is = null;
		Bitmap bmp = null;
		try
		{
			is = MainActivity.assetmgr.open(file);
			bmp = BitmapFactory.decodeStream(is, null, opts);
			is.close();
		}
		catch(Exception e)
		{
			Log.w(Config.TAG,"Could Not Load Bitmap:"+file+" - Error:"+e.getMessage());
			bmp = null;
			if(is!=null)
			{
				try
				{
					is.close();
				}
				catch(Exception e2)
				{
					
				}
			}
			is = null;
		}
		return bmp;
	}
	
	public static String[] ReadAllLines(String filename)
	{
		Log.i(Config.TAG,"File Reading From:"+filename);
		String[] data = new String[0];
		BufferedReader reader = null;
		try
		{
			reader = new BufferedReader(new InputStreamReader(MainActivity.assetmgr.open(filename)));
			String mline = "";
			int linesread = 0;
			while((mline = reader.readLine())!=null)
			{
				data = (String[])ArrayResize.Resize(data, data.length + 1);
				data[data.length - 1] = mline;
				linesread++;
			}
			Log.i(Config.TAG,"Lines Read:"+linesread);
		}
		catch(Exception e)
		{
			
		}
		finally
		{
			if(reader!=null)
			{
				try
				{
					reader.close();
				}
				catch(Exception e2)
				{
					
				}
			}
		}
		return data;
	}
	
	public static void WriteAllText(String filename,String text)
	{
		//we don't use this....
		
	}
	
	public static void CalibrateFonts()
	{
		double dfactor = (((double)Game.RESOLUTIONX/(double)Game.RESOLUTIONY)*((double)Game.RESOLUTIONX/(double)Game.RESOLUTIONY));
		dfactor/=((((double)MainActivity.actualWidth/(double)MainActivity.actualHeight))*(((double)MainActivity.actualWidth/(double)MainActivity.actualHeight)));
		float factor = (float)dfactor;
		if(Game.LETTERBOX)
		{
			factor*=0.65f;
		}
		
		Game.fonts[Resources.SMALLFONT].ptsize*=Fonts.scale;
		Game.fonts[Resources.FONT].ptsize*=Fonts.scale;
		Game.fonts[Resources.LARGEFONT].ptsize*=Fonts.scale;
		//test it out......
		Bitmap bmp = Bitmap.createBitmap(800, 320, Bitmap.Config.ARGB_8888);
		Paint p = new Paint();
		p.setColor(Color.WHITE);
		p.setTypeface(Game.fonts[Resources.FONT].font);
		p.setTextSize(factor*Game.fonts[Resources.FONT].ptsize/Game.QUALITY);
		Fonts.scale = 1;
		Canvas cnv = new Canvas(bmp);
		
		//do some writing on the canvas....as if it were a button.....
		
		Rect bounds = new Rect();
		bounds.left = 0;
		bounds.top = 0;
		bounds.right = 799;
		bounds.bottom = 319;
		int[] pixels = new int[800*320];
		int its = 0;
		while(bounds.right - bounds.left > 130 || bounds.right - bounds.left < 100)
		{
			its++;
			if(its>20)
			{
				break;
			}
			bounds.left = 0;
			bounds.top = 0;
			bounds.right = 799;
			bounds.bottom = 319;
			bmp.eraseColor(Color.TRANSPARENT);
			cnv.drawText("Campaign", 400, 160, p);
			cnv.drawText("ABCDEFGH", 400, 160, p);
			cnv.drawText("MLNOPQRS", 400, 160, p);
			cnv.drawText("TXRUZJA8", 400, 160, p);
			bmp.getPixels(pixels, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());
			for(int x=1;x<799;x++)
			{
				for(int y=1;y<319;y++)
				{
					if(pixels[x + y * 800]!=Color.TRANSPARENT)
					{
						if(x>bounds.left && bounds.left==0)
						{
							bounds.left = x;
						}
						if(y>bounds.top && bounds.top==0)
						{
							bounds.top = y;
						}
						bounds.right = x;
						bounds.bottom = y;
					}
				}
			}
			float dwidth = 110;
			float awidth = bounds.right - bounds.left;
			if(awidth==0)
			{
				//do nothing....
				Log.i(Config.TAG,"Text Size Not Shown Properly");
				break;
			}
			else
			{
				Game.fonts[Resources.FONT].ptsize += Functions.sign(dwidth - awidth);
				p.setTextSize(factor*Game.fonts[Resources.FONT].ptsize/Game.QUALITY);
			}
		}
		Game.fonts[Resources.SMALLFONT].ptsize = (Game.fonts[Resources.FONT].ptsize * 2) / 3;
		Game.fonts[Resources.LARGEFONT].ptsize = (Game.fonts[Resources.FONT].ptsize * 5) / 3;
		bmp.recycle();
		bmp = null;
		
	}	
}
//
