}//LoadSprite()
		
		/// <summary>
		/// Adds a UI button.		
		/// </summary>
		/// <param name="obj">Parent game object.</param>
		/// <param name="fileName">Resource file name with path, relative to Rersources folder.</param>
		public UIObject Add(UIType type, GameObject obj, string fileName, Sprite spr = null)
		{
			Log.Info("Add: <color=yellow>"+obj.name+" - id:"+obj.GetComponent<GUIText>()+"</color> type:"+type);

			//// Log.GameTimes("_______________-_-_-_-_-_ <color=yellow>"+fileName+" _____ obj: "+obj+"</color>, type: "+type);


			if(images.ContainsKey(obj.GetInstanceID()))
			{
			 	//give warning, then return existing one (ignore new registration)
			 	Log.Debug("This button already registered, ignoring new registration. <color=cyan>" + obj.name+"</color> ");
			 	return images[obj.GetInstanceID()];
			}

			Sprite[] sprList = new Sprite[1];
			if(fileName.Length == 0)
			{

				if(spr == null)
				{
					Log.Debug("This button <color=yellow>"+obj.name+"</color> has no image.");
				}
				else
				{
					Log.Debug("Sprite >>>>>>>>>>>>>>>>> "+spr.name);
					sprList[0] = spr;
				}
			}
			else
			{
				sprList = LoadSprite(fileName);
			}



			UIObject image = null;
			switch(type)
			{
				case UIType.Image:
					Log.Debug("Add UIImage");
					image = new UIImage(obj, sprList);
					break;

				case UIType.Button:
					Log.Debug("Add UIButton");
					image = new UIButton(obj, sprList);
					break;

				case UIType.ToggleButton:
					Log.Debug("Add UIToggleButton");
					image = new UIToggleButton(obj, sprList);
					break;
					
				case UIType.Slider:
					Log.Debug("Add UISlider");
					image = new UISlider(obj, sprList);
					break;

				case UIType.Character:
					Log.Debug("Add UICharacter");
					image = new UICharacter(obj, sprList);
					break;

				case UIType.ChartPie:
					Log.Debug("Add UIChartPie");
					image = new UIChartPie(obj);
					break;

				case UIType.ChartLine:
					Log.Debug("Add UIChartLine");
					image = new UIChartLine(obj);
					break;

				case UIType.Checkbox:
					Log.Debug("Add Checkbox");
					image = new UICheckbox(obj, sprList);
					break;

				default:
					Log.Exception("Invalid UIType to add:" + type);
					break;
			}

			//TODO remove this
			images.Add(obj.GetInstanceID(), image);
			
			//
			//images.Add(""+lastId++, image);
			//Log.Info("Button added:"+obj.name+" image:"+image.Name);

			return image;

		}//Add()
		}//LoadResources()

		/// <summary>
		/// Load object resources from dictionary
		/// TODO make more generic helpers and way of parse similar stuff.
		/// ie. transform parameter should be one parser for all
		/// </summary>
		public Dictionary<string, UIObject> LoadResources(
			Dictionary<string,object> dict, 
		    GameObject                gameObject = null)
		{
			//parse list of objects
			if(dict.ContainsKey("objects"))
			{

				// Log.Debug("Number of objects:"+((List<object>)dict["objects"]).Count);

				Dictionary<string, UIObject> screenObjects = new Dictionary<string, UIObject>();
			
				foreach(Dictionary<string,object> obj
					in ((List<object>)dict["objects"]))
				{
					 
					//Log.Debug("objects:"+obj["id"].ToString()+" type:"+obj["type"].ToString());
	

					if(obj.ContainsKey("type") 
						&& obj.ContainsKey("id"))
					{
						//string objId = obj["id"].ToString();
						
						//get id and prefix it by parent name
						string objId = obj["id"].ToString();						
						if(gameObject!=null) objId = gameObject.name+"."+objId;

						
						string objType = obj["type"].ToString();						
						// Log.Debug("Create ui object:"+objId+":"+objType);

						
						//create objects based on types
						if(objType == "image")
						{
							
							// Log.Debug("Create Image:"+objId);
							//TODO add creation of an image gameObject here or there?
							UIImage image = new UIImage(obj);
							if(gameObject)
								image.GameObject.transform.parent = gameObject.transform;

							image.Name = objId;
							//images.Add(objId, image);
							images.Add(image.GameObject.GetInstanceID(), image);

							screenObjects.Add(obj["id"].ToString(),image);


						}
						else if(objType == "button")
						{
							
							Log.Debug("Create Button:<color=yellow>"+objId+"</color>");
							UIButton button = new UIButton(obj);
							if(gameObject)
							{
								button.GameObject.transform.parent = gameObject.transform;
								button.Name = objId;
							}


							//images.Add(objId, button);
							images.Add(button.GameObject.GetInstanceID(), button);
							screenObjects.Add(obj["id"].ToString(),button);

						}

						else if(objType == "togglebutton" )
						{
							Log.Debug("Create Toggle Button:<color=yellow>"+objId+"</color>");
							UIToggleButton button = new UIToggleButton(obj);
							if(gameObject)
							{
								button.GameObject.transform.parent = gameObject.transform;
								button.Name = objId;
							}

							//TODO FIX_TOGGLE this hack! move button init to Settings.cs to Enter()
							// for SoundButton:
							// 	bool mutedMusic = AUDIO.AudioManager.Instance.MuteMusic;
							// 	bool mutedSfx = AUDIO.AudioManager.Instance.MuteSfx;
							// 	if(((mutedMusic) && (objId == "Settings.btn_Sound")) ||		// sets Sound button
							// 	   ((mutedSfx) && (objId == "Settings.btn_SoundEffects")))	// sets SoundEffects button
							// 	{
							// 		//button.SoundState = UISoundButton.UISoundButtonState.SOUNDOFF;
							// 		//button.SaveState = "Off";
							// 		button.Active = false;
							// 	}

							//images.Add(objId, button);
							images.Add(button.GameObject.GetInstanceID(), button);
							screenObjects.Add(obj["id"].ToString(),button);

						}
						else if(objType == "text")
						{
							
							Log.Debug("Create TEXT:<color=yellow>"+objId+"</color>");
							
							GameObject txt = new GameObject();
							txt.SetActive(false);
							txt.name = objId;
							UIText uiText = txt.AddComponent<UIText>() as UIText;
							uiText.Parse(obj);

							if(gameObject)
								txt.transform.parent = gameObject.transform;


							//images.Add(objId, text);
							txt.SetActive(true);
							screenObjects.Add(obj["id"].ToString(),uiText);

						}
						else if(objType == "popup")
						{
							//set prefab default to id and reset if defined							
							string prefab = (obj.ContainsKey("prefab")) 
								? obj["prefab"].ToString() : obj["id"].ToString();
							
							GameObject popup = GetPopup(obj["id"].ToString(), prefab);
							popup.SetActive(true);

							if(obj.ContainsKey("position"))
							{
								
								string pos = obj["position"].ToString();
								float px = System.Convert.ToSingle(pos.Split(',')[0]);
								float py = System.Convert.ToSingle(pos.Split(',')[1]);
								
								Log.Debug("HUD "+objId+" Position:"+px+","+py);
								popup.transform.position = new Vector3(px, py, 0);
								//this.gameObject.name = dict["position"].ToString();
							}
							if(obj.ContainsKey("rotation"))
							{
								
								string rot = obj["rotation"].ToString();
								float rx = System.Convert.ToSingle(rot.Split(',')[0]);
								float ry = System.Convert.ToSingle(rot.Split(',')[1]);
								
								//Log.Debug("Rotation:"+rot+":"+rx+","+ry);
								popup.transform.localRotation = Quaternion.Euler(new Vector3(rx, ry, 0));
							}
							if(obj.ContainsKey("scale"))
							{
								
								string sc = obj["scale"].ToString();
								float sx = System.Convert.ToSingle(sc.Split(',')[0]);
								float sy = System.Convert.ToSingle(sc.Split(',')[1]);
								
								popup.transform.localScale = new Vector3(sx, sy, 0);
								Log.Debug("Scale:"+sx+","+sy);
							}
							if(dict.ContainsKey("layer"))
							{
								string layer = dict["layer"].ToString();
								popup.layer = LayerMask.NameToLayer(layer);
								ChangeLayers(popup, layer);
								
							}
						}
						else if(objType == "hud")
						{

							//set prefab default to id and reset if defined							
							string prefab = (obj.ContainsKey("prefab")) 
									? obj["prefab"].ToString() : obj["id"].ToString();
							
							//Log.Debug("Create HUD as:"+prefab);
							GameObject hud = GetHud(obj["id"].ToString(), prefab);
							hud.SetActive(true);

							//Log.Warning("dict"+dict["layer"].ToString());
							if(obj.ContainsKey("position"))
							{

								string pos = obj["position"].ToString();
								float px = System.Convert.ToSingle(pos.Split(',')[0]);
								float py = System.Convert.ToSingle(pos.Split(',')[1]);

								Log.Debug("HUD "+objId+" Position:"+px+","+py);
								hud.transform.position = new Vector3(px, py, 0);
								//this.gameObject.name = dict["position"].ToString();
							}
							if(obj.ContainsKey("rotation"))
							{

								string rot = obj["rotation"].ToString();
								float rx = System.Convert.ToSingle(rot.Split(',')[0]);
								float ry = System.Convert.ToSingle(rot.Split(',')[1]);

								//Log.Debug("Rotation:"+rot+":"+rx+","+ry);
								hud.transform.localRotation = Quaternion.Euler(new Vector3(rx, ry, 0));
							}
							if(obj.ContainsKey("scale"))
							{
								string[] sc = obj["scale"].ToString().Split(',');
								float sx = System.Convert.ToSingle(sc[0]);
								float sy = System.Convert.ToSingle(sc[1]);
								float sz = 0;
								if (sc.Length > 2)
								{
									sz = System.Convert.ToSingle(sc[2]);
								}

								hud.transform.localScale = new Vector3(sx, sy, sz);
								Log.Debug(string.Format("Scale: {0}, {1}, {2}", sx, sy, sz));
							}
							// if(obj.ContainsKey("order"))
							// {
							// 	int order = System.Convert.ToInt32(obj["order"].ToString());
							// 	SortingOrder = order;

							// }
							if(obj.ContainsKey("layer"))
							{
								string layer = obj["layer"].ToString();
								hud.layer = LayerMask.NameToLayer(layer);
								ChangeLayers(hud, layer);

							}

							
						}
						else if(objType == "model")
						{
							
							//set prefab default to id and reset if defined							
							string prefab = (obj.ContainsKey("prefab")) 
								? obj["prefab"].ToString() : obj["id"].ToString();
							
							//Log.Debug("Create HUD as:"+prefab);
							GameObject hud = GetModel(obj["id"].ToString(), prefab);
							hud.SetActive(true);
							
							//Log.Warning("dict"+dict["layer"].ToString());
							if(obj.ContainsKey("position"))
							{
								
								string pos = obj["position"].ToString();
								float px = System.Convert.ToSingle(pos.Split(',')[0]);
								float py = System.Convert.ToSingle(pos.Split(',')[1]);
								float pz = System.Convert.ToSingle(pos.Split(',')[2]);
								
								Log.Debug("Model "+objId+" Position:"+px+","+py+","+pz);
								hud.transform.position = new Vector3(px, py, pz);
								//this.gameObject.name = dict["position"].ToString();
							}
							if(obj.ContainsKey("rotation"))
							{
								
								string rot = obj["rotation"].ToString();
								float rx = System.Convert.ToSingle(rot.Split(',')[0]);
								float ry = System.Convert.ToSingle(rot.Split(',')[1]);
								
								//Log.Debug("Rotation:"+rot+":"+rx+","+ry);
								hud.transform.localRotation = Quaternion.Euler(new Vector3(rx, ry, 0));
							}
							if(obj.ContainsKey("scale"))
							{
								
								string sc = obj["scale"].ToString();
								float sx = System.Convert.ToSingle(sc.Split(',')[0]);
								float sy = System.Convert.ToSingle(sc.Split(',')[1]);
								
								hud.transform.localScale = new Vector3(sx, sy, 0);
								Log.Debug("Scale:"+sx+","+sy);
							}
							// if(obj.ContainsKey("order"))
							// {
							// 	int order = System.Convert.ToInt32(obj["order"].ToString());
							// 	SortingOrder = order;
							
							// }
							if(obj.ContainsKey("layer"))
							{
								string layer = obj["layer"].ToString();
								hud.layer = LayerMask.NameToLayer(layer);
								ChangeLayers(hud, layer);
								
							}
							
							
						}
						else if(objType == "character")
						{
							
							Log.Debug("Create Character:<color=yellow>"+objId+"</color>");
							UICharacter uiChar = new UICharacter(obj);
							if(gameObject)
							{
								uiChar.GameObject.transform.parent = gameObject.transform;
								uiChar.Name = objId;
							}

							//TODO we might want this later
							//NPCView npcview = uiChar.GameObject.AddComponent<NPCView>();
							//npcview.id = objId;
							//npcview.image = uiChar;

							//read bubble info if any
							//TODO move this somewhere else? Should a bubble exist outside of uichar?
							if(obj.ContainsKey("bubble"))
							{
								foreach(Dictionary<string,object> bobj
									in ((List<object>)obj["bubble"]))
								{
									//TODO parse text parameter. (as text section?) This part is parsed
									//by UIText already, so we should only pass it over.
									//size (of text area), font, fontSize, anchor, alignment, wrapsize
									if(bobj.ContainsKey("position"))
									{

										string pos = bobj["position"].ToString();
										float px = System.Convert.ToSingle(pos.Split(',')[0]);
										float py = System.Convert.ToSingle(pos.Split(',')[1]);
										uiChar.bubblePosition = new Vector3(px, py, 0);
										Log.Debug("HUD "+objId+" bubble.Position:"+px+","+py);
									}

									if(bobj.ContainsKey("scale"))
									{

										string sc = bobj["scale"].ToString();
										float  sx = System.Convert.ToSingle(sc.Split(',')[0]);
										float  sy = System.Convert.ToSingle(sc.Split(',')[1]);
										uiChar.bubbleScale = new Vector3(sx, sy, 1);
										//Log.Debug("---------- bubble.scale:"+sx+","+sy);
									}

									if(bobj.ContainsKey("tail"))
									{

										uiChar.bubbleTail = bobj["tail"].ToString();
										
									}

								}
							}
							


							images.Add(uiChar.GameObject.GetInstanceID(), uiChar);
							screenObjects.Add(obj["id"].ToString(),uiChar);

						}
						else if(objType == "skit")
						{
							UISkit uiSkit = new UISkit(obj);
							if(gameObject)
							{
								uiSkit.GameObject.transform.parent = gameObject.transform;
								uiSkit.Name = objId;
							}

							if(obj.ContainsKey("bubble"))
							{
								foreach(Dictionary<string,object> bobj in ((List<object>)obj["bubble"]))
								{
									//TODO parse text parameter. (as text section?) This part is parsed
									//by UIText already, so we should only pass it over.
									//size (of text area), font, fontSize, anchor, alignment, wrapsize
									if(bobj.ContainsKey("position"))
									{

										string pos = bobj["position"].ToString();
										float px = System.Convert.ToSingle(pos.Split(',')[0]);
										float py = System.Convert.ToSingle(pos.Split(',')[1]);
										uiSkit.bubblePosition = new Vector3(px, py, 0);
									}

									if(bobj.ContainsKey("scale"))
									{

										string sc = bobj["scale"].ToString();
										float sx = System.Convert.ToSingle(sc.Split(',')[0]);
										float sy = System.Convert.ToSingle(sc.Split(',')[1]);
										uiSkit.bubbleScale = new Vector3(sx, sy, 1);
									}

									if(bobj.ContainsKey("tail"))
									{
										uiSkit.bubbleTail = bobj["tail"].ToString();
									}
								}
							}

							images.Add(uiSkit.GameObject.GetInstanceID(), uiSkit);
							screenObjects.Add(obj["id"].ToString(), uiSkit);
						}
						else if(objType == "video")
						{
							//Log.Info(" ---------------------------- -- ");
							//create canvas
							GameObject canvas = GameObject.CreatePrimitive(PrimitiveType.Quad);					
							GameObject.Destroy(canvas.GetComponent("MeshCollider"));
							canvas.name = objId;
							if(gameObject)
								canvas.transform.parent = gameObject.transform;

							UIVideo video = new UIVideo(canvas, obj);

							images.Add(video.GameObject.GetInstanceID(), video);
							screenObjects.Add(obj["id"].ToString(),video);

						}
					}
					else
					{
						Log.Error("Object missing id and/or type definition");
					}
				}

				return screenObjects;

			}

			return null;
		}//LoadResources()