public void addBranchesToLimb(TreePart limb, int limbRemaining)
        {
            int    branchSections = (int)(limbRemaining * species.averageBranchLength + (random.NextDouble() * species.branchLengthVariation - species.branchLengthVariation / 2));
            Branch newBranch      = new Branch(this, species.getRect(species.weightedBranchRects, random));

            limb.addPart(newBranch);
            float initialRot = (float)(random.NextDouble() * (Math.PI * 2f));

            newBranch.rotation = initialRot;
            newBranch.performSetup();
            for (int i = 0; i < branchSections; i++)
            {
                Branch newSection = new Branch(this, species.getRect(species.weightedBranchRects, random));
                newBranch.findAnyEnd().addPart(newSection);
                newSection.rotation = ((float)(random.NextDouble() * 0.5 - 0.25f));
                newSection.performSetup();
            }

            Rectangle   leafSprite  = species.getRect(species.weightedLeafRects, random);
            LeafCluster leafCluster = new LeafCluster(this, leafSprite, species.getColor(species.weightedLeafColors, leafSprite, random));

            newBranch.findAnyEnd().addPart(leafCluster);
            leafCluster.depth -= (float)(random.NextDouble() + 0.5);
            leafCluster.performSetup();
            Logger.log("Leaf cluster is on " + (leafCluster.left ? "left" : "right"));
        }
        public void buildStructure()
        {
            treeStructure = new Stump(this, species.getRect(species.weightedStumpRects, random));
            int trunkLength = species.minHeight + (seed % species.heightVariation);

            Logger.log("Tree is " + trunkLength + " units tall.");

            int firstLimbHeight = (int)(species.minLimbHeight + random.NextDouble() * species.minLimbHeightVariation);

            //int sectionsBetweenLimbs = 0;

            if (species.form == Species.FORM_OPEN)
            {
                for (int i = 0; i < trunkLength; i++)
                {
                    Trunk newSection = new Trunk(this, species.getRect(species.weightedTrunkRects, random));
                    newSection.rotation = ((float)random.NextDouble() * 1f) - 0.5f;
                    //newSection.rotation = 0.3f;
                    treeStructure.findAnyEnd(new Type[] { typeof(Trunk), typeof(Stump) }).addPart(newSection);
                    newSection.performSetup();
                    //&& i - firstLimbHeight >= sectionsBetweenLimbs
                    if (i >= firstLimbHeight && random.NextDouble() <= species.limbFrequency)
                    {
                        Logger.log("Adding limbs to section " + i);
                        if (species.limbAlternate)
                        {
                            addLimbToPart(newSection, random.Next(2) == 0, i, trunkLength - i);
                        }
                        else
                        {
                            addLimbToPart(newSection, true, i, trunkLength - i);
                            addLimbToPart(newSection, false, i, trunkLength - i);
                        }
                        //sectionsBetweenLimbs = (int)(averageLimbInterval + (random.NextDouble() * limbIntervalVariation) - (limbIntervalVariation / 2));
                    }
                    //else if (i >= firstLimbHeight)
                    //{
                    //    sectionsBetweenLimbs--;
                    //}
                }
                addLimbToPart(treeStructure.findAnyEnd(new Type[] { typeof(Trunk), typeof(Stump) }), random.Next(2) == 0, trunkLength, species.minHeight / 2);
            }

            else if (species.form == Species.FORM_CONICAL)
            {
                for (int i = 0; i < trunkLength; i++)
                {
                    if (i == trunkLength - 1)
                    {
                        Logger.log("Trunk has become vertical limb...");
                        addLimbToPart(treeStructure.findAnyEnd(new Type[] { typeof(Trunk), typeof(Stump) }), random.Next(2) == 0, trunkLength, 2, 0f);
                    }
                    else if (species.limbGrowth * (trunkLength - i) <= 1 || i >= trunkLength - 2)
                    {
                        Trunk newSection = new Trunk(this, species.getRect(species.weightedLimbRects, random));
                        newSection.rotation = ((float)random.NextDouble() * 1f) - 0.5f;
                        treeStructure.findAnyEnd(new Type[] { typeof(Trunk), typeof(Stump) }).addPart(newSection);
                        newSection.performSetup();

                        Logger.log("Adding branches to small section " + i);

                        addBranchesToLimb(newSection, trunkLength - i);
                    }
                    else if (i >= firstLimbHeight && random.NextDouble() <= species.limbFrequency)
                    {
                        Trunk newSection = new Trunk(this, species.getRect(species.weightedTrunkRects, random));
                        newSection.rotation = ((float)random.NextDouble() * 1f) - 0.5f;
                        treeStructure.findAnyEnd(new Type[] { typeof(Trunk), typeof(Stump) }).addPart(newSection);
                        newSection.performSetup();

                        Logger.log("Adding limb to section " + i);
                        if (species.limbAlternate)
                        {
                            addLimbToPart(newSection, random.Next(2) == 0, i, trunkLength - i);
                        }
                        else
                        {
                            addLimbToPart(newSection, true, i, trunkLength - i);
                            addLimbToPart(newSection, false, i, trunkLength - i);
                        }
                    }
                }
            }
            else if (species.form == Species.FORM_LINEAR)
            {
                for (int i = 0; i < trunkLength; i++)
                {
                    Trunk newSection = new Trunk(this, species.getRect(species.weightedTrunkRects, random));
                    newSection.rotation = ((float)random.NextDouble() * species.maxTrunkWobble) - (species.maxTrunkWobble / 2f);
                    treeStructure.findAnyEnd(new Type[] { typeof(Trunk), typeof(Stump) }).addPart(newSection);
                    newSection.performSetup();
                    if (i == trunkLength - 1)
                    {
                        Rectangle   leafSprite  = species.getRect(species.weightedLeafRects, random);
                        LeafCluster leafCluster = new LeafCluster(this, leafSprite, species.getColor(species.weightedLeafColors, leafSprite, random));
                        leafCluster.left = random.NextDouble() >= 0.5;
                        newSection.addPart(leafCluster);
                        leafCluster.depth -= (float)(random.NextDouble() + 0.5);
                        leafCluster.performSetup();
                    }
                }
            }

            else if (species.form == Species.FORM_SPREADING)
            {
                for (int i = 0; i < trunkLength; i++)
                {
                    List <TreePart> currentEnds = treeStructure.findAllEnds(new Type[] { typeof(Trunk), typeof(Stump) });
                    foreach (TreePart currentEnd in currentEnds)
                    {
                        float splitChance = species.limbFrequency / currentEnds.Count;
                    }
                }
            }
        }