/*
 * 
 * Reputation System    -   Minoc Blacksmithing Association Example
 * Beta Version 2.3
 * Designed for SVN 663 + ML
 * 
 * Authored by Dougan Ironfist
 * Last Updated on 3/5/2011
 * 
 * The purpose of these scripts is to allow shard administrators to create reputation groups that allow players to complete
 * quests, kill specific creatures and purchase items from reputation vendors based on their current reputation level.
 * This system is very similiar to how reputation systems work in other games.
 * 
 */

using System;
using System.Collections.Generic;
using Server;
using Server.Mobiles;
using Server.Gumps;
using Server.Items;
using Server.Engines.Craft;
using Server.Engines.Quests;
using Server.Reputation;
using Server.Reputation.Items;
using Server.Reputation.Quest;

/// THIS IS AN EXAMPLE SCRIPT AND MAY BE USED TO CREATE ADDITIONAL REPUTATION GROUPS ///

namespace Server.Reputation.MinocBlacksmithAssociation.Quest
{
    public class MBA_CraftQuestRevised : ReputationQuest
    {
        // This must contain an instance of your reputation group
        public override BaseReputationGroup RepGroup { get { return new MinocBlacksmithAssociation(); } }

        /*
         * This routine is used to determine if reputation can be awarded for this quest.
         * 
         * This routine, in combination with the creature killing hook found the reputation group definition, can be used to
         * create complex conditions on how players can earn reputation.
         * 
         * Consider the following example:
         *      The creature killing hook allows player to gain reputation up to Well Known by killing lizardmen.
         *      
         *      At the same time, the player can complete quests that allows him/her to gain reputation up to Trusted.
         *      
         *      In order to attain Member reputation, a second section of the creature killing hook allows the players
         *      to gain reputation up to Member by killing Dragons.
         */
        public override bool CanAssignReputation(PlayerMobile player)
        {
            return base.CanAssignReputation(player);
        }

        public MBA_CraftQuestRevised()
            : base()
        {
        }

        public override void InitializeQuest(PlayerMobile from, BaseReputationQuestGiver questGiver)
        {
            // Use this variable to specify the name of your kill quest
            QuestName = "Minoc Brigade Resupply Quest";

            // The CraftCount variable is used to specify the number of items the player must make and turn in to complete the quest
            double theirSkill = from.Skills[SkillName.Blacksmith].Base;

            if (theirSkill >= 70.1)
                GoalAmount = Utility.RandomList(10, 15, 20, 20);
            else if (theirSkill >= 50.1)
                GoalAmount = Utility.RandomList(10, 15, 15, 20);
            else
                GoalAmount = Utility.RandomList(10, 10, 15, 20);

            double excChance = 0.0;

            if (theirSkill >= 70.1)
                excChance = (theirSkill + 80.0) / 200.0;

            // Specify whether the items must be exceptional crafted
            RequireExceptional = (excChance > Utility.RandomDouble());

            // This section is used to generate the Item that the player must craft
            // Begin Section
            OrderEntry entry;

            if (Utility.RandomBool())
                entry = OrderEntry.RandomEntry(from, OrderEntry.Armors, RequireExceptional);
            else
                entry = OrderEntry.RandomEntry(from, OrderEntry.Weapons, RequireExceptional);

            if (entry == null)
                entry = new OrderEntry("Buckler", typeof(Buckler), 0.0);
            // End Section

            GoalName = entry.ItemName;      // Specify the name of the item the player must craft
            GoalType = entry.ItemType;      // Specify the Type of the item the player must craft

            // Use this variable to specify the text of the quest offer
            CustomDescription = String.Format("The Minoc Brigade has been working overtime to push back the PKs in the mines.  As a result they have nearly exhausted their supply of weapons and armor.  The Minoc Blacksmithing Association would like to enlist you, {0}, to craft {1} {2}{3}.  You will be rewarded for your efforts.", from.Name, GoalAmount, (RequireExceptional ? "Exceptional " : ""), GoalName);

            // Use this variable to specify the text that is displayed when talking to the quest giver during the quest
            CustomUncomplete = String.Format("Please craft {0} {1}{2} and mark them as quest items in order to receive your reward.",
                GoalAmount, (RequireExceptional ? "Exceptional " : ""), GoalName);

            // Use this variable to specify the text that is displayed when the player completes the quest
            CustomComplete = String.Format("Thank you, {0}, for your hard work.  Please accept this reward for your labors.", from.Name);

            // Use this variable to specify the text that is displayed if the quest is refused
            CustomRefuse = String.Format("Very well. Perhaps you will have time to assist us another time.",
                questGiver.Name);

            int bonus = (GoalAmount - 10) / 5;

            if (entry.MinSkill >= 90.0)
                bonus += 3;
            else if (entry.MinSkill >= 75.0)
                bonus += 2;
            else if (entry.MinSkill >= 50.0)
                bonus += 1;

            ReputationRewarded = 250;                       // Specify the number of reputation points the player will receive upon completion

            AddObjective(new CraftObjective(GoalType, GoalName, GoalAmount, RequireExceptional));
            AddReward(new BaseReward(typeof(SmallBlacksmithRewardBag), "Small Blacksmith Reward Bag"));
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            // Add null objectives to allow for proper deserialization
            AddObjective(new CraftObjective(null, null, -1, false));

            base.Deserialize(reader);

            int version = reader.ReadInt();

            // Initialize quest parameters after deserialization completes
            CraftObjective o = (CraftObjective)Objectives[0];
            o.Obtain = GoalType;
            o.Name = GoalName;
            o.MaxProgress = GoalAmount;

            // Reinitialize quest rewards
            AddReward(new BaseReward(typeof(SmallBlacksmithRewardBag), "Small Blacksmith Reward Bag"));
        }

        #region OrderEntry
        // This is a private class modelled after the BOD system that is used to determine the item the player needs to craft
        private class OrderEntry
        {
            public string ItemName;
            public Type ItemType;
            public double MinSkill;

            public OrderEntry(string itemName, Type itemType)
            {
                ItemName = itemName;
                ItemType = itemType;
                MinSkill = 0.0;
            }

            public OrderEntry(string itemName, Type itemType, double minSkill)
            {
                ItemName = itemName;
                ItemType = itemType;
                MinSkill = minSkill;
            }

            public static OrderEntry RandomEntry(PlayerMobile player, List<OrderEntry> entries, bool reqExceptional)
            {
                CraftSystem system = DefBlacksmithy.CraftSystem;

                List<OrderEntry> validEntries = new List<OrderEntry>();

                for (int i = 0; i < entries.Count; ++i)
                {
                    CraftItem item = system.CraftItems.SearchFor(entries[i].ItemType);

                    if (item != null)
                    {
                        bool allRequiredSkills = true;
                        double chance = item.GetSuccessChance(player, null, system, false, ref allRequiredSkills);

                        double minSkill = 0.0;

                        foreach (CraftSkill skill in item.Skills)
                            if (skill.MinSkill > minSkill)
                                minSkill = skill.MinSkill;

                        if (allRequiredSkills && chance >= 0.0)
                        {
                            if (reqExceptional)
                                chance = item.GetExceptionalChance(system, chance, player);

                            if (chance > 0.0)
                            {
                                entries[i].MinSkill = minSkill;
                                validEntries.Add(entries[i]);
                            }
                        }
                    }
                }

                if (validEntries.Count > 0)
                    return validEntries[Utility.Random(validEntries.Count)];

                return null;
            }

            public static List<OrderEntry> Weapons
            {
                get
                {
                    List<OrderEntry> entries = new List<OrderEntry>();

                    entries.Add(new OrderEntry("Axe", typeof(Axe)));
                    entries.Add(new OrderEntry("Battle Axe", typeof(BattleAxe)));
                    entries.Add(new OrderEntry("Dagger", typeof(Dagger)));
                    entries.Add(new OrderEntry("Double Axe", typeof(DoubleAxe)));
                    entries.Add(new OrderEntry("Executioner's Axe", typeof(ExecutionersCap)));
                    entries.Add(new OrderEntry("Large Battle Axe", typeof(LargeBattleAxe)));
                    entries.Add(new OrderEntry("Two Handed Axe", typeof(TwoHandedAxe)));
                    entries.Add(new OrderEntry("War Axe", typeof(WarAxe)));
                    entries.Add(new OrderEntry("Hammer Pick", typeof(HammerPick)));
                    entries.Add(new OrderEntry("Mace", typeof(Mace)));
                    entries.Add(new OrderEntry("Maul", typeof(Maul)));
                    entries.Add(new OrderEntry("War Hammer", typeof(WarHammer)));
                    entries.Add(new OrderEntry("War Mace", typeof(WarMace)));
                    entries.Add(new OrderEntry("Bardiche", typeof(Bardiche)));
                    entries.Add(new OrderEntry("Halberd", typeof(Halberd)));
                    entries.Add(new OrderEntry("Spear", typeof(Spear)));
                    entries.Add(new OrderEntry("Short Spear", typeof(ShortSpear)));
                    entries.Add(new OrderEntry("War Fork", typeof(WarFork)));
                    entries.Add(new OrderEntry("Broadsword", typeof(Broadsword)));
                    entries.Add(new OrderEntry("Cutlass", typeof(Cutlass)));
                    entries.Add(new OrderEntry("Katana", typeof(Katana)));
                    entries.Add(new OrderEntry("Kryss", typeof(Kryss)));
                    entries.Add(new OrderEntry("Longsword", typeof(Longsword)));
                    entries.Add(new OrderEntry("Scimitar", typeof(Scimitar)));
                    entries.Add(new OrderEntry("Thin Longsword", typeof(ThinLongsword)));
                    entries.Add(new OrderEntry("Viking Sword", typeof(VikingSword)));

                    return entries;
                }
            }

            public static List<OrderEntry> Armors
            {
                get
                {
                    List<OrderEntry> entries = new List<OrderEntry>();

                    entries.Add(new OrderEntry("Chain Chest", typeof(ChainChest)));
                    entries.Add(new OrderEntry("Chain Legs", typeof(ChainLegs)));
                    entries.Add(new OrderEntry("Bascinet", typeof(Bascinet)));
                    entries.Add(new OrderEntry("Chain Coif", typeof(ChainCoif)));
                    entries.Add(new OrderEntry("Close Helm", typeof(CloseHelm)));
                    entries.Add(new OrderEntry("Helmet", typeof(Helmet)));
                    entries.Add(new OrderEntry("Norse Helm", typeof(NorseHelm)));
                    entries.Add(new OrderEntry("Plate Helm", typeof(PlateHelm)));
                    entries.Add(new OrderEntry("Female Plate Chest", typeof(FemalePlateChest)));
                    entries.Add(new OrderEntry("Plate Arms", typeof(PlateArms)));
                    entries.Add(new OrderEntry("Plate Chest", typeof(PlateChest)));
                    entries.Add(new OrderEntry("Plate Gloves", typeof(PlateGloves)));
                    entries.Add(new OrderEntry("Plate Gorget", typeof(PlateGorget)));
                    entries.Add(new OrderEntry("Plate Legs", typeof(PlateLegs)));
                    entries.Add(new OrderEntry("Ringmail Arms", typeof(RingmailArms)));
                    entries.Add(new OrderEntry("Ringmail Chest", typeof(RingmailChest)));
                    entries.Add(new OrderEntry("Ringmail Gloves", typeof(RingmailGloves)));
                    entries.Add(new OrderEntry("Ringmail Legs", typeof(RingmailLegs)));
                    entries.Add(new OrderEntry("Bronze Shield", typeof(BronzeShield)));
                    entries.Add(new OrderEntry("Buckler", typeof(Buckler)));
                    entries.Add(new OrderEntry("Heater Shield", typeof(HeaterShield)));
                    entries.Add(new OrderEntry("Metal Kite Shield", typeof(MetalKiteShield)));
                    entries.Add(new OrderEntry("Metal Shield", typeof(MetalShield)));
                    entries.Add(new OrderEntry("Wooden Kite Shield", typeof(WoodenKiteShield)));

                    return entries;
                }
            }
        }
        #endregion
    }
}