﻿using System.Collections.Generic;
using UnityEngine;
using SanAndreasUnity.Behaviours;
using SanAndreasUnity.Utilities;
using System.Linq;

namespace SanAndreasUnity.UI {

	public class MapWindow : PauseMenuWindow {

		public static MapWindow Instance { get; private set; }

		//private	Rect	visibleMapRect = new Rect ();
		private	Vector2	m_focusPos = Vector2.one * MiniMap.mapSize / 2.0f;
		private	float	zoomLevel = 1;
		private	float	infoAreaHeight = 90;
		private	bool	m_clipMapItems = false;

		private	Texture2D	m_infoAreaTexture;

		private	float	m_playerPointerSize = 10;
		public float PlayerPointerSize { get => m_playerPointerSize; set { m_playerPointerSize = value; } }
		private	bool	m_drawZones = false;
		private bool m_drawEnexes = false;

		private	bool	m_isWaypointPlaced = false;
		private	Vector2	m_waypointMapPos = Vector2.zero;

		private	Vector2	m_lastMousePosition = Vector2.zero;

		private	Vector2	m_infoAreaScrollViewPos = Vector2.zero;

		public event System.Action onDrawMapItems = delegate {};



		MapWindow() {

			// set default parameters

			this.windowName = "Map";
			this.useScrollView = false;
			this.isDraggable = false;
			this.isModal = true;
			this.m_hasExitButton = false;
			this.m_hasMinimizeButton = false;

		}

		protected override void Awake () {
			
			base.Awake();

			if (null == Instance)
				Instance = this;

			m_infoAreaTexture = F.CreateTexture (1, 1, Color.grey);

		}

		void Start () {

			this.RegisterButtonInPauseMenu ();

			// adjust rect
			this.windowRect = Utilities.GUIUtils.GetCenteredRectPerc (new Vector2 (1.0f, 1.0f));

		}

		protected	override	void	OnWindowOpened() {

			this.FocusOnPlayer ();

		}


		public	void	FocusOnPlayer() {

			if (null == Ped.Instance)
				return;

			Vector3 playerWorldPos = Ped.Instance.transform.position;
			//	Vector2 focusWorldPos = new Vector2 (playerWorldPos.x, playerWorldPos.z);
			//	Vector2 focusPosNormalized = focusPos / MiniMap.mapEdge;
			Vector2 focusPos = MiniMap.WorldPosToMapPos(playerWorldPos);

			// flip y axis
		//	focusPos.y = MiniMap.mapSize - focusPos.y;

			this.SetFocusPosition (focusPos);

		}

		public	void	SetFocusPosition(Vector2 pos) {

		//	Vector2 bottomLeftPos = pos;
		//	bottomLeftPos.x -= this.visibleMapRect.width / 2.0f;
		//	bottomLeftPos.y -= this.visibleMapRect.height / 2.0f;

		//	this.visibleMapRect.position = bottomLeftPos;

			this.m_focusPos = pos;

		}

		public	Vector2	GetFocusPosition() {

		//	return this.visibleMapRect.position + this.visibleMapRect.size / 2.0f;
			return this.m_focusPos;
		}


		/// <summary>
		/// Rect in which the map is displayed, relative to window area.
		/// </summary>
		public	Rect	GetMapDisplayRect() {

			float mapDisplayWidth = this.windowRect.width;
			float mapDisplayHeight = this.windowRect.height - this.infoAreaHeight;
			Rect mapDisplayRect = new Rect (0, 0, mapDisplayWidth, mapDisplayHeight);
			return mapDisplayRect;
		}

		public	Vector2	GetVisibleMapSize() {

			Rect mapDisplayRect = this.GetMapDisplayRect ();

			float visibleMapWidth = Mathf.Min( MiniMap.mapSize / 4.0f / this.zoomLevel, MiniMap.mapSize);
			float visibleMapHeight = Mathf.Min (visibleMapWidth * mapDisplayRect.height / mapDisplayRect.width, MiniMap.mapSize);

			return new Vector2 (visibleMapWidth, visibleMapHeight);
		}

		public	Rect	GetVisibleMapRect() {

			Vector2 size = GetVisibleMapSize ();

			return new Rect (this.m_focusPos - size / 2.0f, size);
		}

//		private	void	AdjustVisibleMapRectAfterZooming() {
//
//			Vector2 focusPos = this.GetFocusPosition ();
//
//			// visible map size is changed after zooming
//			Vector2 size = this.GetVisibleMapSize ();
//
//			this.visibleMapRect = new Rect(focusPos - size / 2.0f, size);
//
//		}


		public	static	Vector2	ClampPositionInsideMap(Vector2 pos) {

			pos.x = Mathf.Clamp( pos.x, 0.0f, MiniMap.mapSize);
			pos.y = Mathf.Clamp( pos.y, 0.0f, MiniMap.mapSize);

			return pos;
		}

		private	void	ClampFocusPos() {

			// clamp focus position inside map
			this.SetFocusPosition (ClampPositionInsideMap (this.GetFocusPosition ()));

			// again, clamp focus position, but based on visible map rectangle - the rectangle must not go out of map boundaries, or the texture will stretch
//			Vector2 visibleMapSize = this.GetVisibleMapSize();
//			if (visibleMapSize.x < GetMapSize ()) {
//				this.m_focusPos.x = Mathf.Clamp (this.m_focusPos.x, GetMinMapPos ().x + visibleMapSize.x / 2.0f, GetMaxMapPos ().x - visibleMapSize.x / 2.0f);
//			}
//			if (visibleMapSize.y < GetMapSize ()) {
//				this.m_focusPos.y = Mathf.Clamp (this.m_focusPos.y, GetMinMapPos ().y + visibleMapSize.y / 2.0f, GetMaxMapPos ().y - visibleMapSize.y / 2.0f);
//			}

		}

		public	static	Vector2	GetMinMapPos() {
			return Vector2.zero;
		}

		public	static	Vector2	GetMaxMapPos() {
			return Vector2.one * MiniMap.mapSize;
		}

		public	static	float	GetMapSize() {
			return MiniMap.mapSize;
		}


		public	Vector2	ScreenPosToDisplayPos(Vector2 screenPos) {

			Rect displayRect = this.GetMapDisplayRect ();

			Vector2 displayPos = screenPos - displayRect.position;
			// flip Y axis
			displayPos.y = Screen.height - displayPos.y;

			return displayPos;
		}

		public	bool	GetMapPosUnderMouse(out Vector2 mapPos) {

			mapPos = Vector2.zero;

			Vector2 displayPos = ScreenPosToDisplayPos (m_lastMousePosition);

			// check if it is inside display rect
			if (!this.GetMapDisplayRect ().Contains (displayPos))
				return false;

			mapPos = DisplayPosToMapPos (displayPos);

			return true;
		}

		public	bool	GetWorldPosUnderMouse(out Vector3 worldPos) {

			worldPos = Vector3.zero;

			Vector2 mapPos;
			if(!this.GetMapPosUnderMouse(out mapPos))
				return false;

			worldPos = MiniMap.MapPosToWorldPos (mapPos);

			return true;
		}

		public	Vector2	DisplayPosToMapPos(Vector2 displayPos) {

			Rect mapDisplayRect = this.GetMapDisplayRect ();
			Rect visibleMapRect = this.GetVisibleMapRect ();

			// don't know why is this needed
			// flip Y axis
			displayPos.y = mapDisplayRect.height - displayPos.y;

			Vector2 normalizedPos = Rect.PointToNormalized (mapDisplayRect, displayPos);

			Vector2 mapPos = Rect.NormalizedToPoint (visibleMapRect, normalizedPos);

			return mapPos;
		}


		private	void	TeleportToWaypoint() {

			if (!m_isWaypointPlaced)
				return;

			if (null == Ped.Instance)
				return;

			Vector3 worldPos = MiniMap.MapPosToWorldPos (m_waypointMapPos);

			if (Utilities.NetUtils.IsServer)
				Ped.Instance.Teleport (worldPos);
			else if (Net.PlayerRequests.Local != null)
				Net.PlayerRequests.Local.RequestTeleport(worldPos, Ped.Instance.transform.rotation);

		}


		void Update() {

			if (Input.GetKeyDown (KeyCode.M)) {
				// toggle map

				if (this.IsOpened || GameManager.CanPlayerReadInput())
				{

					if (this.IsOpened)
					{
						this.IsOpened = false;
						// also close pause menu
						PauseMenu.IsOpened = false;
					}
					else
					{
						this.IsOpened = true;
						// also open pause menu
						PauseMenu.IsOpened = true;
					}

				}

			}


			if (!PauseMenu.IsOpened || !this.IsOpened)
				return;
			

			// move focused position

			this.m_focusPos += new Vector2 (Input.GetAxisRaw ("Horizontal"), Input.GetAxisRaw("Vertical")) 
				* 100 * Time.deltaTime / this.zoomLevel;

			this.ClampFocusPos ();


			// zoom

			float oldZoomLevel = this.zoomLevel;

			if (Input.GetKey (KeyCode.KeypadPlus)) {
				zoomLevel *= 1.1f;
			}

			if (Input.GetKey (KeyCode.KeypadMinus)) {
				zoomLevel /= 1.1f;
			}

			// mouse scroll
			if (Input.mouseScrollDelta.y > 0)
				zoomLevel *= 1.1f;
			else if(Input.mouseScrollDelta.y < 0)
				zoomLevel /= 1.1f;

			zoomLevel = Mathf.Clamp (zoomLevel, 0.25f, 10f);

			if (oldZoomLevel != this.zoomLevel) {
			//	this.AdjustVisibleMapRectAfterZooming ();
			}


			// toggle waypoint on map

			if (Input.GetMouseButtonDown (1)) {

				Vector2 mouseMapPos;
				if (this.GetMapPosUnderMouse (out mouseMapPos)) {
					m_isWaypointPlaced = !m_isWaypointPlaced;
					if (m_isWaypointPlaced)
						m_waypointMapPos = mouseMapPos;
				}

			}

			// focus on player key shortcut
			if (Input.GetKeyDown (KeyCode.F)) {
				this.FocusOnPlayer ();
			}

			// teleport to waypoint key shortcut
			if (Input.GetKeyDown (KeyCode.T)) {
				this.TeleportToWaypoint ();
			}

			// remember last mouse position
			m_lastMousePosition = Input.mousePosition;


		}


		protected override void OnWindowGUI ()
		{

			if (null == MiniMap.Instance)
				return;


			int uiSize = (int) this.windowRect.width;
			Texture2D mapTexture = MiniMap.Instance.MapTexture;
			Texture2D blackPixel = MiniMap.Instance.BlackPixel;
			Texture2D seaPixel = MiniMap.Instance.SeaPixel;


			Rect mapDisplayRect = this.GetMapDisplayRect ();
			Rect visibleMapRect = this.GetVisibleMapRect ();
		//	this.visibleMapRect.size = this.GetVisibleMapSize();



			//if (!toggleMap) {
			if(false) {
				
				//GUILayout.BeginArea (new Rect (Screen.width - uiSize - 10, uiSize + 20, uiSize, 80));

				GUIStyle style = new GUIStyle ("label") { alignment = TextAnchor.MiddleCenter };


				// draw some info in upper left corner

				Vector2 labelSize = new Vector2 (uiSize, 25);
				Rect labelRect = new Rect (Vector2.zero, labelSize);

				GUI.DrawTexture (labelRect, blackPixel);
				if (Ped.Instance != null) {
					Vector3 pPos = Ped.Instance.transform.position;
					GUI.Label (labelRect,
						string.Format ("x: {0}, y: {1}, z: {2}", pPos.x.ToString ("F2"), pPos.y.ToString ("F2"), pPos.z.ToString ("F2")),
						style);
				}


				// draw zone name

				//Rect zoneRect = new Rect (uiSize / 2 - uiSize / (2 * 3), 25, uiSize / 3, 25);

				//GUI.DrawTexture (zoneRect, blackPixel);
				//GUI.Label (zoneRect, ZoneName, style);


				bool showZoomPanel = true;
				if (showZoomPanel) {
					// display zoom panel

					Color previousColor = GUI.color;

					Rect zoomPanel = new Rect (uiSize / 2 - uiSize / (2 * 4), 55, uiSize / 4, 25);

					float fAlpha = 1;

					GUI.color = new Color (0, 0, 0, fAlpha);

					// fill everything with black
					GUI.DrawTexture (zoomPanel, blackPixel);

					GUI.color = new Color (255, 255, 255, fAlpha);

					// display zoom percentage
					float curZoomPercentage = 1;
					GUI.Label (zoomPanel, string.Format ("x{0}", curZoomPercentage.ToString ("F2")), style);

					GUI.color = previousColor;
				}


				//GUILayout.EndArea ();

			} else {
				
				//mapRect = new Vector2 (mapTexture.width, mapTexture.height) * (baseScale * (mapScale / mapMaxScale) * 2);

				// fill everything with black - why ?
				//GUI.DrawTexture (new Rect (50, 50, Screen.width - 100, Screen.height - 100), blackPixel);

				// fill everything with sea
				GUI.DrawTexture (mapDisplayRect, seaPixel);

				//GUILayout.BeginArea (new Rect (mapUpperLeftCorner, windowSize));

				//GUILayout.BeginArea (new Rect (mapScroll, mapRect));

				// draw the map texture
				this.DrawMapTexture( mapDisplayRect, visibleMapRect );

				// what's this ?
				//GUI.DrawTexture (new Rect (Vector2.zero, Vector2.one * 16), blackPixel);


				//GUILayout.EndArea ();
				//GUILayout.EndArea ();


				// draw 2 lines crossing under cursor
				Vector2 mouseDisplayPos = ScreenPosToDisplayPos( m_lastMousePosition );
				float linesWidth = 4;
				Color linesColor = (Color.yellow + Color.black) / 2.0f;
				// vertical line
				GUIUtils.DrawRect (new Rect(mouseDisplayPos.x - linesWidth / 2.0f, 0, linesWidth, mapDisplayRect.height), linesColor);
				// horizontal line
				GUIUtils.DrawRect (new Rect(0, mouseDisplayPos.y - linesWidth / 2.0f, mapDisplayRect.width, linesWidth), linesColor);


				// draw map items
				this.DrawMapItems (mapDisplayRect);


				// draw info area
				this.DrawInfoArea( mapDisplayRect );

			}

		}

		private	void	DrawMapTexture(Rect mapDisplayRect, Rect visibleMapRect) {

			Texture2D mapTexture = MiniMap.Instance.MapTexture;


			//GUI.DrawTexture (new Rect (mapZoomPos, mapRect), mapTexture);
			//GUI.DrawTexture (new Rect (Vector2.zero, this.windowRect.size), MiniMap.Instance.MapTexture);

			Rect texCoords = new Rect(visibleMapRect.x / mapTexture.width, visibleMapRect.y / mapTexture.height,
				visibleMapRect.width / mapTexture.width, visibleMapRect.height / mapTexture.height);

			texCoords = Utilities.F.Clamp01 (texCoords);

			// adjust display rect

			Rect renderRect = mapDisplayRect;
		//	float mulX = mapDisplayRect.width / GetMapSize ();
		//	float mulY = mapDisplayRect.height / GetMapSize ();

			if(visibleMapRect.xMax > GetMapSize()) {
				// reduce display width
			//	renderRect.width -= (visibleMapRect.xMax - GetMapSize()) * mulX ;
				float perc = (visibleMapRect.xMax - GetMapSize()) / visibleMapRect.width;
				renderRect.xMax -= perc * mapDisplayRect.width;
			}
			if (visibleMapRect.xMin < 0) {
				// increase x pos
			//	renderRect.xMin += - visibleMapRect.xMin * mulX;
				float perc = - visibleMapRect.xMin / visibleMapRect.width;
				renderRect.xMin += perc * mapDisplayRect.width;
			}
			if(visibleMapRect.yMax > GetMapSize()) {
				// reduce display height from top
			//	renderRect.yMin += (visibleMapRect.yMax - GetMapSize()) * mulY ;
				float perc = (visibleMapRect.yMax - GetMapSize()) / visibleMapRect.height;
				renderRect.yMin += perc * mapDisplayRect.height;
			}
			if (visibleMapRect.yMin < 0) {
				// reduce display height from bottom
			//	renderRect.yMax -= - visibleMapRect.yMin * mulY;
				float perc = - visibleMapRect.yMin / visibleMapRect.height;
				renderRect.yMax -= perc * mapDisplayRect.height;
			}

		//	mapTexture.wrapMode = TextureWrapMode.Clamp;

			GUI.DrawTextureWithTexCoords(renderRect, mapTexture, texCoords);

		}

		private	void	DrawInfoArea (Rect mapDisplayRect) {


			Rect infoAreaRect = new Rect (3, mapDisplayRect.yMax, mapDisplayRect.width - 3, this.infoAreaHeight);

			GUILayout.BeginArea (infoAreaRect);
			GUI.DrawTexture (new Rect(new Vector2(-infoAreaRect.x, 0), infoAreaRect.size), m_infoAreaTexture);

			m_infoAreaScrollViewPos = GUILayout.BeginScrollView (m_infoAreaScrollViewPos);

			GUILayout.Space (10);

			// first row - controls
			GUILayout.BeginHorizontal (GUILayout.MaxWidth (infoAreaRect.width));

			if (GUILayout.Button ("Focus on player [F]", GUILayout.MinHeight(25))) {
				this.FocusOnPlayer ();
			}
			if (GUILayout.Button ("Teleport to waypoint [T]", GUILayout.MinHeight(25))) {
				this.TeleportToWaypoint ();
			}
			GUILayout.Space (5);
			GUILayout.Label ("Player size: " + (int) m_playerPointerSize, GUILayout.ExpandWidth(false));
			m_playerPointerSize = GUILayout.HorizontalSlider (m_playerPointerSize, 1, 50, GUILayout.MinWidth(40));
			m_drawZones = GUILayout.Toggle (m_drawZones, "Draw zones");
			m_drawEnexes = GUILayout.Toggle(m_drawEnexes, "Draw enexes");

			GUILayout.EndHorizontal ();

			// second row - info
			GUILayout.BeginHorizontal (GUILayout.MaxWidth (infoAreaRect.width));

			if (Ped.Instance != null)
			{
				GUILayout.Label ("Player world pos: " + Ped.Instance.transform.position);
				GUILayout.Space (5);
				GUILayout.Label ("Player minimap pos: " + MiniMap.WorldPosToMapPos (Ped.Instance.transform.position));
				GUILayout.Space (5);
			}
			GUILayout.Label ("Focus pos: " + this.GetFocusPosition ());
			GUILayout.Space (5);
			Vector2 cursorMapPos;
			if (this.GetMapPosUnderMouse (out cursorMapPos))
				GUILayout.Label ("Cursor pos: " + cursorMapPos);
			GUILayout.Space (5);
			GUILayout.Label ("Zoom: " + this.zoomLevel);
			// zone name under cursor
			GUILayout.Space (5);
			Vector3 mouseWorldPos;
			if (this.GetWorldPosUnderMouse (out mouseWorldPos)) {
				GUILayout.Label ("cursor world pos: " + mouseWorldPos);
				GUILayout.Label ("Zone: " + Zone.GetZoneName (mouseWorldPos, true), GUILayout.Width(80));
			}

			GUILayout.EndHorizontal ();

			GUILayout.Space (5);
			GUILayout.Label ("Controls: arrows/WASD - move, +/-/scroll - zoom, right click - place waypoint");

			GUILayout.EndScrollView ();

			GUILayout.EndArea ();

		}

		private	void	DrawMapItems(Rect mapDisplayRect) {


			if (!m_clipMapItems) {
				GUI.EndClip ();
				//	GUI.EndGroup ();
			} else {
				GUI.BeginGroup (mapDisplayRect);	// ensure that all map items are drawn inside this rect - doesn't work when items are rotated
			}


			// draw registered items
			onDrawMapItems();

			// draw enexes
			if (m_drawEnexes)
			{
				foreach (var enex in Importing.Items.Item.Enexes.Where(enex => enex.TargetInterior == 0))
				{
					this.DrawItemOnMap(MiniMap.Instance.GreenHouseTexture, enex.EntrancePos, 10);
				}
			}

			// draw player pointer
			if (Ped.Instance != null)
			{
				this.DrawItemOnMapRotated( MiniMap.Instance.PlayerBlip, Ped.Instance.transform.position, Ped.Instance.transform.forward, (int) m_playerPointerSize );
			}

			// draw all zones
			if (m_drawZones) {
				
				foreach (var zone in Zone.AllZones) {
					
					Vector2 min = MiniMap.WorldPosToMapPos (zone.vmin);
					Vector2 max = MiniMap.WorldPosToMapPos (zone.vmax);
					Rect rect = new Rect (min, max - min);

					Rect renderRect;
					if (this.GetMapItemRenderRect (rect, out renderRect)) {
						if (renderRect.height > 2 && renderRect.width > 2)
						{
							// add some space between zones
							renderRect.xMin ++;
							renderRect.xMax --;
							renderRect.yMin ++;
							renderRect.yMax --;

							GUI.Box (renderRect, "");
							GUIUtils.CenteredLabel (renderRect.center, zone.name);
						}
					}

				}
			}

			// draw waypoint
			if (m_isWaypointPlaced) {
				this.DrawItemOnMap (MiniMap.Instance.WaypointTexture, m_waypointMapPos, 12);
			}


			if (!m_clipMapItems) {
				//	GUI.BeginGroup (new Rect (0, 0, Screen.width, Screen.height));
				GUI.BeginClip (this.windowRect);
			} else {
				GUI.EndGroup ();
			}


		}


		public	bool	GetMapItemRenderRect( Rect itemMapBoundsRect, out Rect renderRect ) {

			renderRect = Rect.zero;

		//	Texture2D mapTexture = MiniMap.Instance.MapTexture;

			Rect visibleMapRect = this.GetVisibleMapRect ();

			if (!visibleMapRect.Overlaps (itemMapBoundsRect) && !visibleMapRect.Contains (itemMapBoundsRect)) {
			//	Debug.LogFormat ("Item rect {0} is not within visible rect {1}", itemRect, visibleMapRect);
				return false;
			}

			// just convert map pos to screen pos
			Rect displayRectNormalized = itemMapBoundsRect.Normalized( visibleMapRect );



			/*
			// get intersection between these rects
			Rect intersectionRect = itemRect.Intersection (visibleMapRect);

			Rect displayRectNormalized = intersectionRect.Normalized (visibleMapRect);
		//	displayRectNormalized.y = 1.0f - displayRectNormalized.y;
			Rect texCoords = intersectionRect.Normalized (itemRect);


			// just in case
			displayRectNormalized = displayRectNormalized.Clamp01();
			texCoords = texCoords.Clamp01 ();
			*/


			// adjust display rect

			Rect mapDisplayRect = this.GetMapDisplayRect ();
			Vector2 renderRectPos = mapDisplayRect.position + Vector2.Scale (mapDisplayRect.size, displayRectNormalized.position);
			renderRectPos.y = mapDisplayRect.height - renderRectPos.y;
			Vector2 renderRectSize = Vector2.Scale (mapDisplayRect.size, displayRectNormalized.size);
			renderRectPos.y -= renderRectSize.y;
			renderRect = new Rect (renderRectPos, renderRectSize);


		//	GUI.DrawTextureWithTexCoords(renderRect, itemTexture, texCoords);


		//	Debug.LogFormat ("Drawn item: item rect {0} visible map rect {1} intersection rect {2} displayRectNormalized {3} " +
		//	"texCoords {4} mapDisplayRect {5} renderRect {6}", itemRect, visibleMapRect, intersectionRect, displayRectNormalized,
		//		texCoords, mapDisplayRect, renderRect);

			return true;
		}

		public	void	DrawItemOnMap( Texture2D itemTexture, Rect itemRect ) {

			Rect renderRect;
			if (GetMapItemRenderRect (itemRect, out renderRect)) {
				GUI.DrawTexture (renderRect, itemTexture);
			}

		}

		public	void	DrawItemOnMap( Texture2D itemTexture, Vector2 mapPos, int itemSize ) {

			this.DrawItemOnMap (itemTexture, F.CreateRect (mapPos, Vector2.one * itemSize));

		}

		public	void	DrawItemOnMap( Texture2D itemTexture, Vector3 worldPos, int itemSize ) {

			Vector2 mapPos = MiniMap.WorldPosToMapPos (worldPos);

			this.DrawItemOnMap (itemTexture, mapPos, itemSize);

		}

		public	void	DrawItemOnMapRotated( Texture2D itemTexture, Vector3 worldPos, Vector3 worldDir, int itemSize ) {

			Vector2 mapPos = MiniMap.WorldPosToMapPos (worldPos);

			this.DrawItemOnMapRotated (itemTexture, F.CreateRect (mapPos, Vector2.one * itemSize), worldDir);

		}

		public	void	DrawItemOnMapRotated( Texture2D itemTexture, Rect itemRect, Vector3 worldDir ) {

			Rect renderRect;
			if (!GetMapItemRenderRect (itemRect, out renderRect)) {
				return;
			}


			// find angle around Y axis
			Vector3 dir = new Vector3(worldDir.x, 0, worldDir.z).normalized;
			Quaternion q = Quaternion.LookRotation (dir, Vector3.up);
			float angle = q.eulerAngles.y - 180.0f;

			// save matrix
			var oldMatrix = GUI.matrix;

			// rotate around center of item
			GUIUtility.RotateAroundPivot( angle, renderRect.center );

			// draw
			GUI.DrawTexture (renderRect, itemTexture);

			// restore matrix
			GUI.matrix = oldMatrix;


		}


	}

}
