context: using UnityEngine;
  using UnityEngine.Events;
  using System.Collections;
  using System.Collections.Generic;
  
  namespace UnityEngine.UI
  {
  	[AddComponentMenu("UI/Bars/Step Bar")]
  	public class UIStepBar : MonoBehaviour {
  		
  		[System.Serializable]
  		public struct StepFillInfo
  		{
  			public int index;
  			public float amount;
  		}
  		
  		[SerializeField] private List<GameObject> m_StepsGameObjects = new List<GameObject>();
  		[SerializeField] private List<StepFillInfo> m_OverrideFillList = new List<StepFillInfo>();
  		
  		[SerializeField] private GameObject m_StepsGridGameObject;
  		[SerializeField] private RectTransform m_StepsGridRect;
  		[SerializeField] private GridLayoutGroup m_StepsGrid;
  		
  		[SerializeField] private int m_CurrentStep = 0;
  		[SerializeField] private int m_StepsCount = 1;
  		[SerializeField] private RectOffset m_StepsGridPadding = new RectOffset();
  		[SerializeField] private Sprite m_SeparatorSprite;
  		[SerializeField] private Sprite m_SeparatorSpriteActive;
  		[SerializeField] private Color m_SeparatorSpriteColor = Color.white;
  		[SerializeField] private bool m_SeparatorAutoSize = true;
  		[SerializeField] private Vector2 m_SeparatorSize = Vector2.zero;
  		[SerializeField] private Image m_FillImage;
  		[SerializeField] private RectTransform m_BubbleRect;
  		[SerializeField] private Vector2 m_BubbleOffset = Vector2.zero;
  		[SerializeField] private Text m_BubbleText;
  		
  		/// <summary>
  		/// Gets or sets the current step.
  		/// </summary>
  		/// <value>The value.</value>
  		public int step
  		{
  			get { return this.m_CurrentStep; }
  			set { this.GoToStep(value); }
  		}
  		
  		/// <summary>
  		/// Determines whether this instance is active.
  		/// </summary>
  		/// <returns><c>true</c> if this instance is active; otherwise, <c>false</c>.</returns>
  		public virtual bool IsActive()
  		{
  			return this.enabled && this.gameObject.activeInHierarchy;
  		}
  		
  		protected virtual void Start()
  		{
  			this.UpdateBubble();
  		}
  
  #if UNITY_EDITOR
          /// <summary>
          /// Editor only!
          /// </summary>
          public void RebuildSteps_Editor()
          {
              // Create the steps grid if required
              this.CreateStepsGrid();
  
              // Update the grid properties
              this.UpdateGridProperties();
  
              // Rebuild the steps if required
              this.RebuildSteps();
  
              // Update the steps properties
              this.UpdateStepsProperties();
          }
  
  		/// <summary>
  		/// Raises the validate event.
  		/// </summary>
  		protected virtual void OnValidate()
  		{
  			// Validate the step integers
  			if (this.m_CurrentStep < 0) this.m_CurrentStep = 0;
  			if (this.m_StepsCount < 1) this.m_StepsCount = 1;
  			if (this.m_CurrentStep > this.m_StepsCount) this.m_CurrentStep = this.m_StepsCount + 1;
  			
  			// Create the steps grid if required
  			this.CreateStepsGrid();
  			
  			// Update the grid properties
  			this.UpdateGridProperties();
  			
  			// Rebuild the steps if required
  			//this.RebuildSteps();
  			
  			// Update the steps properties
  			this.UpdateStepsProperties();
  			
  			// Validate the fill image
  			if (this.m_FillImage != null)
  			{
  				// Validate the image type
  				if (this.m_FillImage.type != Image.Type.Filled)
  					this.m_FillImage.type = Image.Type.Filled;
  				
  				// Validate the fill method
  				if (this.m_FillImage.fillMethod != Image.FillMethod.Horizontal)
  					this.m_FillImage.fillMethod = Image.FillMethod.Horizontal;
  					
  				// Update the fill amount
  				this.UpdateFillImage();
  			}
  			
  			// Update the bubble
  			this.UpdateBubble();
  		}
  #endif
  
  		/// <summary>
  		/// Gets the fill override values list.
  		/// </summary>
  		/// <returns>The override fill list.</returns>
  		public List<StepFillInfo> GetOverrideFillList()
  		{
  			return this.m_OverrideFillList;
  		}
  		
  		/// <summary>
  		/// Sets the fill override values list.
  		/// </summary>
  		/// <param name="list">List.</param>
  		public void SetOverrideFillList(List<StepFillInfo> list)
  		{
  			this.m_OverrideFillList = list;
  		}
  		
  		/// <summary>
  		/// Validates the fill override values list.
  		/// </summary>
  		public void ValidateOverrideFillList()
  		{
  			// Create a temporary list
  			List<StepFillInfo> list = new List<StepFillInfo>();
  			
  			// Copy the current list to array
  			StepFillInfo[] tempArr = this.m_OverrideFillList.ToArray();
  			
  			// Loop
  			foreach (StepFillInfo info in tempArr)
  			{
  				// Add all the valid step infos to the temporary list
  				if (info.index > 1 && info.index <= this.m_StepsCount && info.amount > 0f)
  					list.Add(info);
  			}
  			
  			// Set the temporary list as the override list
  			this.m_OverrideFillList = list;
  		}
  		
  		/// <summary>
  		/// Raises the rect transform dimensions change event.
  		/// </summary>
  		protected virtual void OnRectTransformDimensionsChange()
  		{
  			if (!this.IsActive())
  				return;
  			
  			this.UpdateGridProperties();
  		}
  		
  		/// <summary>
  		/// Goes to the specified step.
  		/// </summary>
  		/// <param name="step">Step.</param>
  		public void GoToStep(int step)
  		{
  			// Validate the step
  			if (step < 0) step = 0;
  			if (step > this.m_StepsCount) step = this.m_StepsCount + 1;
  			
  			// Set the step
  			this.m_CurrentStep = step;
  			
  			// Update the steps properties
  			this.UpdateStepsProperties();
  			
  			// Update the fill amount
  			this.UpdateFillImage();
  			
  			// Update the bubble
  			this.UpdateBubble();
  		}
  		
  		/// <summary>
  		/// Updates the fill image.
  		/// </summary>
  		public void UpdateFillImage()
  		{
  			if (this.m_FillImage == null)
  				return;
  			
  			int overrideIndex = this.m_OverrideFillList.FindIndex(x => x.index == this.m_CurrentStep);
  			
  			// Apply fill amount
  			this.m_FillImage.fillAmount = (overrideIndex >= 0) ? this.m_OverrideFillList[overrideIndex].amount : this.GetStepFillAmount(this.m_CurrentStep);
  		}
  		
  		/// <summary>
  		/// Updates the bubble.
  		/// </summary>
  		public void UpdateBubble()
  		{
  			if (this.m_BubbleRect == null)
  				return;
  			
  			// Determine if the bubble should be visible
  			if (this.m_CurrentStep > 0 && this.m_CurrentStep <= this.m_StepsCount)
  			{
  				// Activate if required
  				if (!this.m_BubbleRect.gameObject.activeSelf)
  					this.m_BubbleRect.gameObject.SetActive(true);
  				
  				// Get the step game object
  				GameObject stepObject = this.m_StepsGameObjects[this.m_CurrentStep];
  				
  				if (stepObject != null)
  				{
  					RectTransform stepRect = stepObject.transform as RectTransform;
  					
  					if (stepRect.anchoredPosition.x != 0f)
  					{
  						// Update the bubble position based on the location of the step
  						this.m_BubbleRect.anchoredPosition = new Vector2(this.m_BubbleOffset.x + (stepRect.anchoredPosition.x + (stepRect.rect.width / 2f)), this.m_BubbleOffset.y);
  					}
  				}
  
                  // Update the bubble text
                  if (this.m_BubbleText != null)
                      this.m_BubbleText.text = this.m_CurrentStep.ToString();
  			}
  			else
  			{
  				// Deactivate if required
  				if (this.m_BubbleRect.gameObject.activeSelf)
  					this.m_BubbleRect.gameObject.SetActive(false);
  			}
  		}
  		
  		/// <summary>
  		/// Gets the step fill amount.
  		/// </summary>
  		/// <returns>The step fill amount.</returns>
  		/// <param name="step">Step.</param>
  		public float GetStepFillAmount(int step)
  		{
  			return ((1f / (float)(this.m_StepsCount + 1)) * (float)step);
  		}
  		
  		/// <summary>
  		/// Creates the steps grid.
  		/// </summary>
  		protected void CreateStepsGrid()
  		{
  			if (this.m_StepsGridGameObject != null)
  				return;
  			
  			// Create new game object
  			this.m_StepsGridGameObject = new GameObject("Steps Grid", typeof(RectTransform), typeof(GridLayoutGroup));
  			this.m_StepsGridGameObject.layer = this.gameObject.layer;
  			this.m_StepsGridGameObject.transform.SetParent(this.transform, false);
  			this.m_StepsGridGameObject.transform.SetAsLastSibling();
  			
  			// Get the rect transform
  			this.m_StepsGridRect = this.m_StepsGridGameObject.GetComponent<RectTransform>();
  			this.m_StepsGridRect.sizeDelta = new Vector2(0f, 0f);
  			this.m_StepsGridRect.anchorMin = new Vector2(0f, 0f);
  			this.m_StepsGridRect.anchorMax = new Vector2(1f, 1f);
  			this.m_StepsGridRect.pivot = new Vector2(0f, 1f);
  			this.m_StepsGridRect.anchoredPosition = new Vector2(0f, 0f);
  			
  			// Get the grid layout group
  			this.m_StepsGrid = this.m_StepsGridGameObject.GetComponent<GridLayoutGroup>();
  			
  			// Set the bubble as last sibling
  			if (this.m_BubbleRect != null)
  				this.m_BubbleRect.SetAsLastSibling();
  		}
  		
  		/// <summary>
  		/// Updates the grid properties.
  		/// </summary>
  		public void UpdateGridProperties()
  		{
  			if (this.m_StepsGrid == null)
  				return;
  
              int seps = this.m_StepsCount + 2;
  
              // Grid Padding
              if (!this.m_StepsGrid.padding.Equals(this.m_StepsGridPadding))
  				this.m_StepsGrid.padding = this.m_StepsGridPadding;
  			
  			// Auto sizing
  			if (this.m_SeparatorAutoSize && this.m_SeparatorSprite != null)
  			{
  				this.m_SeparatorSize = new Vector2(this.m_SeparatorSprite.rect.width, this.m_SeparatorSprite.rect.height);
  			}
  			
  			if (!this.m_StepsGrid.cellSize.Equals(this.m_SeparatorSize))
  				this.m_StepsGrid.cellSize = this.m_SeparatorSize;
  			
  			// Grid spacing
  			float spacingX = Mathf.Floor((this.m_StepsGridRect.rect.width - (float)this.m_StepsGridPadding.horizontal - ((float)seps * this.m_SeparatorSize.x)) / (float)(seps - 1) / 2f) * 2f;
  			
  			if (this.m_StepsGrid.spacing.x != spacingX)
  				this.m_StepsGrid.spacing = new Vector2(spacingX, 0f);
  		}
  		
  		/// <summary>
  		/// Rebuilds the steps.
  		/// </summary>
  		public void RebuildSteps()
  		{
  			if (this.m_StepsGridGameObject == null)
  				return;
  			
  			// Check if we already have the steps
  
gt: 			if (this.m_StepsGameObjects.Count == this.m_StepsCount)