public WindowComponentNavigation GetNavigation(Vector3 dir, NavigationSideInfo sideInfo)
        {
            var navTarget = this.FindSelectable(dir, sideInfo, pointOnEdge: true) as WindowComponentNavigation;

            if (navTarget == null)
            {
                navTarget = this.FindSelectable(dir, sideInfo, pointOnEdge: false) as WindowComponentNavigation;
            }
            return(navTarget);
        }
        public void SetNavigationInfo(NavigationSide side, NavigationSideInfo info)
        {
            switch (side)
            {
            case NavigationSide.Down:
                this.navigateDownInfo = info;
                break;

            case NavigationSide.Up:
                this.navigateUpInfo = info;
                break;

            case NavigationSide.Left:
                this.navigateLeftInfo = info;
                break;

            case NavigationSide.Right:
                this.navigateRightInfo = info;
                break;
            }
        }
        public WindowComponentNavigation GetNavigation(NavigationSide side)
        {
            var dir      = Vector3.zero;
            var rotation = this.GetRectTransform().rotation;
            var sideInfo = new NavigationSideInfo();

            switch (side)
            {
            case NavigationSide.Left:
                dir      = rotation * Vector3.left;
                sideInfo = this.navigateLeftInfo;
                break;

            case NavigationSide.Right:
                dir      = rotation * Vector3.right;
                sideInfo = this.navigateRightInfo;
                break;

            case NavigationSide.Up:
                dir      = rotation * Vector3.up;
                sideInfo = this.navigateUpInfo;
                break;

            case NavigationSide.Down:
                dir      = rotation * Vector3.down;
                sideInfo = this.navigateDownInfo;
                break;
            }

            if (sideInfo.@explicit == true)
            {
                return(sideInfo.next);
            }

            return(this.GetNavigation(dir, sideInfo));
        }
		public WindowComponentNavigation FindSelectable(Vector3 dir, NavigationSideInfo sideInfo) {

			if (sideInfo.stop == true) return null;

			var navGroup = this.GetNavigationGroup();
			if (navGroup == null) return null;

			dir = dir.normalized;
			var localDir = Quaternion.Inverse(transform.rotation) * dir;
			var pos = transform.TransformPoint(WindowComponentNavigation.GetPointOnRectEdge(transform as RectTransform, localDir));
			var maxScore = Mathf.NegativeInfinity;

			var components = navGroup.GetNavigationComponents();

			WindowComponentNavigation bestPick = null;
			for (int i = 0; i < components.Count; ++i) {
				
				var sel = components[i] as WindowComponentNavigation;
				if (sel == this || sel == null) continue;

				var selInteractable = sel as IInteractableStateComponent;
				if (selInteractable != null) {

					if (selInteractable.GetNavigationType() == NavigationType.None ||
						selInteractable.IsVisible() == false ||
					    (
							selInteractable.IsNavigateOnDisabled() == false &&
							selInteractable.IsInteractable() == false
					    ))
						continue;

				} else {
					
					if (sel.GetNavigationType() == NavigationType.None ||
						sel.IsVisible() == false)
						continue;
					
				}

				var selRect = sel.GetRectTransform();
				var selCenter = selRect != null ? selRect.rect.center.XY() : Vector3.zero;
				var myVector = selRect.TransformPoint(selCenter) - pos;

				if (sideInfo.directionAxisOnly == true) {

					if (dir.x == 0f) myVector.x = 0f;
					if (dir.y == 0f) myVector.y = 0f;

				}

				var dot = Vector3.Dot(dir, myVector);
				if (dot <= 0f) continue;

				var score = dot / myVector.sqrMagnitude;
				if (score > maxScore) {
					
					maxScore = score;
					bestPick = sel;

				}

			}

			return bestPick;

		}
		public WindowComponentNavigation GetNavigation(Vector3 dir, NavigationSideInfo sideInfo) {

			return this.FindSelectable(dir, sideInfo) as WindowComponentNavigation;

		}
		public WindowComponentNavigation GetNavigation(NavigationSide side) {

			var dir = Vector3.zero;
			var rotation = this.GetRectTransform().rotation;
			NavigationSideInfo sideInfo = new NavigationSideInfo();
			switch (side) {

				case NavigationSide.Left:
					dir = rotation * Vector3.left;
					sideInfo = this.navigateLeftInfo;
					break;

				case NavigationSide.Right:
					dir = rotation * Vector3.right;
					sideInfo = this.navigateRightInfo;
					break;

				case NavigationSide.Up:
					dir = rotation * Vector3.up;
					sideInfo = this.navigateUpInfo;
					break;

				case NavigationSide.Down:
					dir = rotation * Vector3.down;
					sideInfo = this.navigateDownInfo;
					break;

			}

			if (sideInfo.@explicit == true) {
				
				return sideInfo.next;

			}

			return this.GetNavigation(dir, sideInfo);

		}
		public void SetNavigationInfo(NavigationSide side, NavigationSideInfo info) {

			switch (side) {

				case NavigationSide.Down:
					this.navigateDownInfo = info;
					break;

				case NavigationSide.Up:
					this.navigateUpInfo = info;
					break;

				case NavigationSide.Left:
					this.navigateLeftInfo = info;
					break;

				case NavigationSide.Right:
					this.navigateRightInfo = info;
					break;

			}

		}
        public WindowComponentNavigation FindSelectable(Vector3 dir, NavigationSideInfo sideInfo, bool pointOnEdge = true)
        {
            if (sideInfo.stop == true)
            {
                return(null);
            }

            var navGroup = this.GetNavigationGroup();

            if (navGroup == null)
            {
                return(null);
            }

            dir = dir.normalized;
            var tr       = this.transform as RectTransform;
            var localDir = Quaternion.Inverse(tr.rotation) * dir;
            var pos      = tr.TransformPoint(pointOnEdge == true ? WindowComponentNavigation.GetPointOnRectEdge(tr, localDir) : (Vector3)tr.rect.center);
            var maxScore = Mathf.NegativeInfinity;

            var components = navGroup.GetNavigationComponents();

            WindowComponentNavigation bestPick = null;

            for (int i = 0; i < components.Count; ++i)
            {
                var sel = components[i] as WindowComponentNavigation;
                if (sel == this || sel == null)
                {
                    continue;
                }

                var selInteractable = sel as IInteractableStateComponent;
                if (selInteractable != null)
                {
                    if (selInteractable.GetNavigationType() == NavigationType.None ||
                        (
                            selInteractable.IsNavigateOnDisabled() == false &&
                            selInteractable.IsVisible() == false
                        ) ||
                        (
                            selInteractable.IsNavigateOnDisabled() == false &&
                            selInteractable.IsInteractable() == false
                        ))
                    {
                        continue;
                    }
                }
                else
                {
                    if (sel.GetNavigationType() == NavigationType.None ||
                        sel.IsVisible() == false)
                    {
                        continue;
                    }
                }

                var selRect   = sel.GetRectTransform();
                var selCenter = selRect != null?selRect.rect.center.XY() : Vector3.zero;

                var myVector = selRect.TransformPoint(selCenter) - pos;

                if (sideInfo.directionAxisOnly == true)
                {
                    if (dir.x == 0f)
                    {
                        myVector.x = 0f;
                    }
                    if (dir.y == 0f)
                    {
                        myVector.y = 0f;
                    }
                }

                var dot = Vector3.Dot(dir, myVector);
                if (dot <= 0f)
                {
                    continue;
                }

                var score = dot / myVector.sqrMagnitude;
                if (score > maxScore)
                {
                    maxScore = score;
                    bestPick = sel;
                }
            }

            return(bestPick);
        }
        public WindowComponentNavigation GetNavigation(NavigationSide side)
        {
            var dir      = Vector3.zero;
            var rotation = this.GetRectTransform().rotation;
            var sideInfo = new NavigationSideInfo();

            switch (side)
            {
            case NavigationSide.Left:
                dir      = rotation * Vector3.left;
                sideInfo = this.navigateLeftInfo;
                break;

            case NavigationSide.Right:
                dir      = rotation * Vector3.right;
                sideInfo = this.navigateRightInfo;
                break;

            case NavigationSide.Up:
                dir      = rotation * Vector3.up;
                sideInfo = this.navigateUpInfo;
                break;

            case NavigationSide.Down:
                dir      = rotation * Vector3.down;
                sideInfo = this.navigateDownInfo;
                break;
            }

            if (sideInfo.@explicit == true)
            {
                if (sideInfo.next != null)
                {
                    var selInteractable = sideInfo.next as IInteractableStateComponent;
                    if (selInteractable != null)
                    {
                        if (selInteractable.GetNavigationType() == NavigationType.None ||
                            (
                                selInteractable.IsNavigateOnDisabled() == false &&
                                selInteractable.IsVisible() == false
                            ) ||
                            (
                                selInteractable.IsNavigateOnDisabled() == false &&
                                selInteractable.IsInteractable() == false
                            ))
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        if (sideInfo.next.GetNavigationType() == NavigationType.None ||
                            sideInfo.next.IsVisible() == false)
                        {
                            return(null);
                        }
                    }

                    return(sideInfo.next);
                }

                return(null);
            }

            return(this.GetNavigation(dir, sideInfo));
        }
 public WindowComponentNavigation GetNavigation(Vector3 dir, NavigationSideInfo sideInfo)
 {
     return(this.FindSelectable(dir, sideInfo) as WindowComponentNavigation);
 }