/*
 * Bungie.Net API
 *
 * These endpoints constitute the functionality exposed by Bungie.net, both for more traditional website functionality and for connectivity to Bungie video games and their related functionality.
 *
 * The version of the OpenAPI document: 2.18.0
 * Contact: support@bungie.com
 * Generated by: https://github.com/openapitools/openapi-generator.git
 */


using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System.ComponentModel.DataAnnotations;
using OpenAPIDateConverter = Destiny.Client.OpenAPIDateConverter;

namespace Destiny.Model
{
    /// <summary>
    /// I see you&#39;ve come to find out more about Talent Nodes. I&#39;m so sorry. Talent Nodes are the conceptual, visual nodes that appear on Talent Grids. Talent Grids, in Destiny 1, were found on almost every instanced item: they had Nodes that could be activated to change the properties of the item. In Destiny 2, Talent Grids only exist for Builds/Subclasses, and while the basic concept is the same (Nodes can be activated once you&#39;ve gained sufficient Experience on the Item, and provide effects), there are some new concepts from Destiny 1. Examine DestinyTalentGridDefinition and its subordinates for more information. This is the \&quot;Live\&quot; information for the current status of a Talent Node on a specific item. Talent Nodes have many Steps, but only one can be active at any one time: and it is the Step that determines both the visual and the game state-changing properties that the Node provides. Examine this and DestinyTalentNodeStepDefinition carefully. *IMPORTANT NOTE* Talent Nodes are, unfortunately, Content Version DEPENDENT. Though they refer to hashes for Nodes and Steps, those hashes are not guaranteed to be immutable across content versions. This is a source of great exasperation for me, but as a result anyone using Talent Grid data must ensure that the content version of their static content matches that of the server responses before showing or making decisions based on talent grid data.
    /// </summary>
    [DataContract(Name = "Destiny.DestinyTalentNode")]
    public partial class DestinyDestinyTalentNode : IEquatable<DestinyDestinyTalentNode>, IValidatableObject
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="DestinyDestinyTalentNode" /> class.
        /// </summary>
        /// <param name="nodeIndex">The index of the Talent Node being referred to (an index into DestinyTalentGridDefinition.nodes[]). CONTENT VERSION DEPENDENT..</param>
        /// <param name="nodeHash">The hash of the Talent Node being referred to (in DestinyTalentGridDefinition.nodes). Deceptively CONTENT VERSION DEPENDENT. We have no guarantee of the hash&#39;s immutability between content versions..</param>
        /// <param name="state">An DestinyTalentNodeState enum value indicating the node&#39;s state: whether it can be activated or swapped, and why not if neither can be performed..</param>
        /// <param name="isActivated">If true, the node is activated: it&#39;s current step then provides its benefits..</param>
        /// <param name="stepIndex">The currently relevant Step for the node. It is this step that has rendering data for the node and the benefits that are provided if the node is activated. (the actual rules for benefits provided are extremely complicated in theory, but with how Talent Grids are being used in Destiny 2 you don&#39;t have to worry about a lot of those old Destiny 1 rules.) This is an index into: DestinyTalentGridDefinition.nodes[nodeIndex].steps[stepIndex].</param>
        /// <param name="materialsToUpgrade">If the node has material requirements to be activated, this is the list of those requirements..</param>
        /// <param name="activationGridLevel">The progression level required on the Talent Grid in order to be able to activate this talent node. Talent Grids have their own Progression - similar to Character Level, but in this case it is experience related to the item itself..</param>
        /// <param name="progressPercent">If you want to show a progress bar or circle for how close this talent node is to being activate-able, this is the percentage to show. It follows the node&#39;s underlying rules about when the progress bar should first show up, and when it should be filled..</param>
        /// <param name="hidden">Whether or not the talent node is actually visible in the game&#39;s UI. Whether you want to show it in your own UI is up to you! I&#39;m not gonna tell you who to sock it to..</param>
        /// <param name="nodeStatsBlock">nodeStatsBlock.</param>
        public DestinyDestinyTalentNode(int nodeIndex = default(int), int nodeHash = default(int), int state = default(int), bool isActivated = default(bool), int stepIndex = default(int), List<DestinyDefinitionsDestinyMaterialRequirement> materialsToUpgrade = default(List<DestinyDefinitionsDestinyMaterialRequirement>), int activationGridLevel = default(int), float progressPercent = default(float), bool hidden = default(bool), DestinyDestinyTalentNodeStatBlock nodeStatsBlock = default(DestinyDestinyTalentNodeStatBlock))
        {
            this.NodeIndex = nodeIndex;
            this.NodeHash = nodeHash;
            this.State = state;
            this.IsActivated = isActivated;
            this.StepIndex = stepIndex;
            this.MaterialsToUpgrade = materialsToUpgrade;
            this.ActivationGridLevel = activationGridLevel;
            this.ProgressPercent = progressPercent;
            this.Hidden = hidden;
            this.NodeStatsBlock = nodeStatsBlock;
        }

        /// <summary>
        /// The index of the Talent Node being referred to (an index into DestinyTalentGridDefinition.nodes[]). CONTENT VERSION DEPENDENT.
        /// </summary>
        /// <value>The index of the Talent Node being referred to (an index into DestinyTalentGridDefinition.nodes[]). CONTENT VERSION DEPENDENT.</value>
        [DataMember(Name = "nodeIndex", EmitDefaultValue = false)]
        public int NodeIndex { get; set; }

        /// <summary>
        /// The hash of the Talent Node being referred to (in DestinyTalentGridDefinition.nodes). Deceptively CONTENT VERSION DEPENDENT. We have no guarantee of the hash&#39;s immutability between content versions.
        /// </summary>
        /// <value>The hash of the Talent Node being referred to (in DestinyTalentGridDefinition.nodes). Deceptively CONTENT VERSION DEPENDENT. We have no guarantee of the hash&#39;s immutability between content versions.</value>
        [DataMember(Name = "nodeHash", EmitDefaultValue = false)]
        public int NodeHash { get; set; }

        /// <summary>
        /// An DestinyTalentNodeState enum value indicating the node&#39;s state: whether it can be activated or swapped, and why not if neither can be performed.
        /// </summary>
        /// <value>An DestinyTalentNodeState enum value indicating the node&#39;s state: whether it can be activated or swapped, and why not if neither can be performed.</value>
        [DataMember(Name = "state", EmitDefaultValue = false)]
        public int State { get; set; }

        /// <summary>
        /// If true, the node is activated: it&#39;s current step then provides its benefits.
        /// </summary>
        /// <value>If true, the node is activated: it&#39;s current step then provides its benefits.</value>
        [DataMember(Name = "isActivated", EmitDefaultValue = true)]
        public bool IsActivated { get; set; }

        /// <summary>
        /// The currently relevant Step for the node. It is this step that has rendering data for the node and the benefits that are provided if the node is activated. (the actual rules for benefits provided are extremely complicated in theory, but with how Talent Grids are being used in Destiny 2 you don&#39;t have to worry about a lot of those old Destiny 1 rules.) This is an index into: DestinyTalentGridDefinition.nodes[nodeIndex].steps[stepIndex]
        /// </summary>
        /// <value>The currently relevant Step for the node. It is this step that has rendering data for the node and the benefits that are provided if the node is activated. (the actual rules for benefits provided are extremely complicated in theory, but with how Talent Grids are being used in Destiny 2 you don&#39;t have to worry about a lot of those old Destiny 1 rules.) This is an index into: DestinyTalentGridDefinition.nodes[nodeIndex].steps[stepIndex]</value>
        [DataMember(Name = "stepIndex", EmitDefaultValue = false)]
        public int StepIndex { get; set; }

        /// <summary>
        /// If the node has material requirements to be activated, this is the list of those requirements.
        /// </summary>
        /// <value>If the node has material requirements to be activated, this is the list of those requirements.</value>
        [DataMember(Name = "materialsToUpgrade", EmitDefaultValue = false)]
        public List<DestinyDefinitionsDestinyMaterialRequirement> MaterialsToUpgrade { get; set; }

        /// <summary>
        /// The progression level required on the Talent Grid in order to be able to activate this talent node. Talent Grids have their own Progression - similar to Character Level, but in this case it is experience related to the item itself.
        /// </summary>
        /// <value>The progression level required on the Talent Grid in order to be able to activate this talent node. Talent Grids have their own Progression - similar to Character Level, but in this case it is experience related to the item itself.</value>
        [DataMember(Name = "activationGridLevel", EmitDefaultValue = false)]
        public int ActivationGridLevel { get; set; }

        /// <summary>
        /// If you want to show a progress bar or circle for how close this talent node is to being activate-able, this is the percentage to show. It follows the node&#39;s underlying rules about when the progress bar should first show up, and when it should be filled.
        /// </summary>
        /// <value>If you want to show a progress bar or circle for how close this talent node is to being activate-able, this is the percentage to show. It follows the node&#39;s underlying rules about when the progress bar should first show up, and when it should be filled.</value>
        [DataMember(Name = "progressPercent", EmitDefaultValue = false)]
        public float ProgressPercent { get; set; }

        /// <summary>
        /// Whether or not the talent node is actually visible in the game&#39;s UI. Whether you want to show it in your own UI is up to you! I&#39;m not gonna tell you who to sock it to.
        /// </summary>
        /// <value>Whether or not the talent node is actually visible in the game&#39;s UI. Whether you want to show it in your own UI is up to you! I&#39;m not gonna tell you who to sock it to.</value>
        [DataMember(Name = "hidden", EmitDefaultValue = true)]
        public bool Hidden { get; set; }

        /// <summary>
        /// Gets or Sets NodeStatsBlock
        /// </summary>
        [DataMember(Name = "nodeStatsBlock", EmitDefaultValue = false)]
        public DestinyDestinyTalentNodeStatBlock NodeStatsBlock { get; set; }

        /// <summary>
        /// Returns the string presentation of the object
        /// </summary>
        /// <returns>String presentation of the object</returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("class DestinyDestinyTalentNode {\n");
            sb.Append("  NodeIndex: ").Append(NodeIndex).Append("\n");
            sb.Append("  NodeHash: ").Append(NodeHash).Append("\n");
            sb.Append("  State: ").Append(State).Append("\n");
            sb.Append("  IsActivated: ").Append(IsActivated).Append("\n");
            sb.Append("  StepIndex: ").Append(StepIndex).Append("\n");
            sb.Append("  MaterialsToUpgrade: ").Append(MaterialsToUpgrade).Append("\n");
            sb.Append("  ActivationGridLevel: ").Append(ActivationGridLevel).Append("\n");
            sb.Append("  ProgressPercent: ").Append(ProgressPercent).Append("\n");
            sb.Append("  Hidden: ").Append(Hidden).Append("\n");
            sb.Append("  NodeStatsBlock: ").Append(NodeStatsBlock).Append("\n");
            sb.Append("}\n");
            return sb.ToString();
        }

        /// <summary>
        /// Returns the JSON string presentation of the object
        /// </summary>
        /// <returns>JSON string presentation of the object</returns>
        public virtual string ToJson()
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
        }

        /// <summary>
        /// Returns true if objects are equal
        /// </summary>
        /// <param name="input">Object to be compared</param>
        /// <returns>Boolean</returns>
        public override bool Equals(object input)
        {
            return this.Equals(input as DestinyDestinyTalentNode);
        }

        /// <summary>
        /// Returns true if DestinyDestinyTalentNode instances are equal
        /// </summary>
        /// <param name="input">Instance of DestinyDestinyTalentNode to be compared</param>
        /// <returns>Boolean</returns>
        public bool Equals(DestinyDestinyTalentNode input)
        {
            if (input == null)
            {
                return false;
            }
            return 
                (
                    this.NodeIndex == input.NodeIndex ||
                    this.NodeIndex.Equals(input.NodeIndex)
                ) && 
                (
                    this.NodeHash == input.NodeHash ||
                    this.NodeHash.Equals(input.NodeHash)
                ) && 
                (
                    this.State == input.State ||
                    this.State.Equals(input.State)
                ) && 
                (
                    this.IsActivated == input.IsActivated ||
                    this.IsActivated.Equals(input.IsActivated)
                ) && 
                (
                    this.StepIndex == input.StepIndex ||
                    this.StepIndex.Equals(input.StepIndex)
                ) && 
                (
                    this.MaterialsToUpgrade == input.MaterialsToUpgrade ||
                    this.MaterialsToUpgrade != null &&
                    input.MaterialsToUpgrade != null &&
                    this.MaterialsToUpgrade.SequenceEqual(input.MaterialsToUpgrade)
                ) && 
                (
                    this.ActivationGridLevel == input.ActivationGridLevel ||
                    this.ActivationGridLevel.Equals(input.ActivationGridLevel)
                ) && 
                (
                    this.ProgressPercent == input.ProgressPercent ||
                    this.ProgressPercent.Equals(input.ProgressPercent)
                ) && 
                (
                    this.Hidden == input.Hidden ||
                    this.Hidden.Equals(input.Hidden)
                ) && 
                (
                    this.NodeStatsBlock == input.NodeStatsBlock ||
                    (this.NodeStatsBlock != null &&
                    this.NodeStatsBlock.Equals(input.NodeStatsBlock))
                );
        }

        /// <summary>
        /// Gets the hash code
        /// </summary>
        /// <returns>Hash code</returns>
        public override int GetHashCode()
        {
            unchecked // Overflow is fine, just wrap
            {
                int hashCode = 41;
                hashCode = (hashCode * 59) + this.NodeIndex.GetHashCode();
                hashCode = (hashCode * 59) + this.NodeHash.GetHashCode();
                hashCode = (hashCode * 59) + this.State.GetHashCode();
                hashCode = (hashCode * 59) + this.IsActivated.GetHashCode();
                hashCode = (hashCode * 59) + this.StepIndex.GetHashCode();
                if (this.MaterialsToUpgrade != null)
                {
                    hashCode = (hashCode * 59) + this.MaterialsToUpgrade.GetHashCode();
                }
                hashCode = (hashCode * 59) + this.ActivationGridLevel.GetHashCode();
                hashCode = (hashCode * 59) + this.ProgressPercent.GetHashCode();
                hashCode = (hashCode * 59) + this.Hidden.GetHashCode();
                if (this.NodeStatsBlock != null)
                {
                    hashCode = (hashCode * 59) + this.NodeStatsBlock.GetHashCode();
                }
                return hashCode;
            }
        }

        /// <summary>
        /// To validate all properties of the instance
        /// </summary>
        /// <param name="validationContext">Validation context</param>
        /// <returns>Validation Result</returns>
        IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
        {
            yield break;
        }
    }

}
