private void library_SelectedArtifactChanged(Artifact selectedArtifact)
 {
     //// code to change the selected book
     //throw new NotImplementedException();
 }
 public KeywordPair(string KeywordEnglish, string KeywordFrench, Artifact ArtifactRef)
 {
     this.keyword = new string[2] { KeywordEnglish, KeywordFrench };
     this.artifactRef = ArtifactRef;
 }
 public StemPair(string Stem, KeywordPair KeywordRef, Artifact ArtifactRef)
 {
     this.stem = Stem;
     this.keywordRef = KeywordRef;
     this.artifactRef = ArtifactRef;
 }
        public ArtifactLibrary(string filename)
        {
            artifacts = new List<Artifact>();

            Artifact.LoadStopwords();

            // load the xml doc
            XmlDocument doc = new XmlDocument();
            doc.Load(filename);
            XmlNode worksheet = doc.DocumentElement.ChildNodes[4];
            XmlNode table = worksheet.FirstChild;
            bool firstRow = false;
            int numArtifactsLoaded = 0;
            foreach (XmlNode child in table.ChildNodes)
            {
                // this check is to load only those artifacts whose 512px images exist
                //if (66 < numArtifactsLoaded)
                if (10 < numArtifactsLoaded)
                {
                    break;
                }

                if (child.Name == "Row")
                {
                    if (firstRow == false)
                    {
                        // skip the first row
                        firstRow = true;
                        continue;
                    }
                    if (child.ChildNodes.Count == 29)
                    {
                        Artifact newArtifact = new Artifact(child);
                        numArtifactsLoaded++;
                        if (0 < newArtifact.Materials.Count)
                        {
                            artifacts.Add(newArtifact);
                        }
                    }
                    else
                    {
                        //Console.WriteLine("Not loaded! ChildNodes.Count = " + child.ChildNodes.Count + " -- " + child.ChildNodes[1].InnerText);
                    }
                }
            }

            /*
            //Artifact.CurrentLanguage = Artifact.LANGUAGE_FRENCH;
            FileStream frenchFile = new FileStream("french_spelling.csv", FileMode.Create);
            StreamWriter sw = new StreamWriter(frenchFile);
            foreach (Artifact a in artifacts)
            {
                sw.WriteLine(a.ArticleName);
            }
            sw.Flush();
            frenchFile.Close();
            //*/

            // compute a graph of all artifact keywords/stems
            stemGraph = new Dictionary<string, List<StemPair>>();
            ComputeStemGraph();

            /*
            foreach (Artifact artifact in artifacts)
            {
                int relatedArtifacts = 0;
                foreach (StemPair sp in artifact.Stems)
                {
                    List<StemPair> relatedStems = stemGraph[sp.Stem];
                    relatedArtifacts += relatedStems.Count;
                }
                if (relatedArtifacts < 2)
                {
                    Console.WriteLine(artifact.ArticleName + " has no related artifacts.");
                }
            }

            foreach (string stem in stemGraph.Keys)
            {
                // don't bother printing out the stem graph
                continue;
                List<StemPair> stemList = stemGraph[stem];
                if (100 < stemList.Count)
                {
                    Console.WriteLine(stem + " => ");
                    foreach (StemPair pair in stemList)
                    {
                        Console.WriteLine("\t" + pair.ArtifactRef.ArticleName);
                    }
                }
            }
            //*/

            Dictionary<Material, int> materialsTally = GetMaterialsTally(new List<Material>());
            foreach (Material m in materialsTally.Keys)
            {
                Console.WriteLine(m.PrimaryArray[Artifact.LANGUAGE_ENGLISH] + " / " + m.PrimaryArray[Artifact.LANGUAGE_FRENCH] + ": " + materialsTally[m]);
            }
            //for (int i = 0; i < 10; i++)
            //{
            //    foreach (StemPair stemPair in artifacts[i].Stems)
            //    {
            //        Console.WriteLine(stemPair.Stem + " => " + stemPair.KeywordRef.Keyword);
            //    }
            //    Console.WriteLine("---");
            //}
        }
 public void SelectArtifact(Artifact sArtifact)
 {
     if (artifacts.Contains(sArtifact) == true)
     {
         selectedArtifact = sArtifact;
         if (SelectedArtifactChanged != null)
         {
             SelectedArtifactChanged(selectedArtifact);
         }
     }
 }
        private void library_SelectedArtifactChanged(Artifact selectedArtifact)
        {
            materialConstraints.Clear();

            foreach (MaterialContainer materialContainer in materialList)
            {
                if (selectedArtifact.Materials.Contains(materialContainer.Material) == true)
                {
                    materialContainer.IsConstraint = true;
                    materialConstraints.Add(materialContainer.Material);
                }
            }

            UpdateBlobsFromConstraints();
            RepositionBlobs();
            UpdateArtifactsFromConstraints();
            RepositionArtifacts();
            animationTimer.Start();
        }
        private void library_SelectedArtifactChanged(Artifact selectedArtifact)
        {
            // change the central circle artifact and texture
            artifactCircles[CENTER_CIRCLE_ID].Artifact = selectedArtifact;
            artifactCircles[CENTER_CIRCLE_ID].Circle.Texture = selectedArtifact.Texture;

            Console.WriteLine("*** New selected artifact " + selectedArtifact.ArticleName + ", colors (" + selectedArtifact.Color.ToString() + ") and it's stems:");
            Console.Write("\t");
            foreach (StemPair stempair in selectedArtifact.Stems)
            {
                Console.Write(stempair.Stem + ", ");
            }
            Console.Write("\n");

            List<Artifact> candidateList = new List<Artifact>();
            // use the stem graph to find related artifacts and put all found into a candidate list
            foreach (StemPair sp in selectedArtifact.Stems)
            {
                List<StemPair> relatedStemPairs = bookshelf.Library.StemGraph[sp.Stem];
                foreach (StemPair relatedSP in relatedStemPairs)
                {
                    if (candidateList.Contains(relatedSP.ArtifactRef) == false && relatedSP.ArtifactRef != selectedArtifact)
                    {
                        candidateList.Add(relatedSP.ArtifactRef);
                    }
                }
            }

            List<KeyValuePair<Artifact, float>> weightedCandidateList = new List<KeyValuePair<Artifact, float>>();
            foreach (Artifact a in candidateList)
            {
                float sameStemCount = 0;
                int numMatchedStems = 0;
                foreach (StemPair sp in a.Stems)
                {
                    if (selectedArtifact.Stems.Contains(sp) == true)
                    {
                        sameStemCount += bookshelf.Library.StemGraph[sp.Stem].Count;
                        numMatchedStems++;
                        //sameStemCount++;
                    }
                }
                weightedCandidateList.Add(new KeyValuePair<Artifact, float>(a, sameStemCount / (numMatchedStems * numMatchedStems)));
            }

            // sort based on relevence
            weightedCandidateList.Sort(CompareArtifactSimilarity);
            weightedCandidateList.Reverse();

            /* debugging
            foreach (KeyValuePair<Artifact, float> kvp in weightedCandidateList)
            {
                Artifact a = kvp.Key;
                Console.WriteLine(a.ArticleName);
                Console.Write("\t");
                foreach (StemPair stempair in a.Stems)
                {
                    if (selectedArtifact.Stems.Contains(stempair))
                    {
                        Console.Write(stempair.Stem + ", ");
                    }
                }
                Console.Write("\n\n");
            }
            //*/

            int i;
            lock (artifactCircles)
            {
                for (i = 0; i < MAX_CIRCLES - 1 && i < weightedCandidateList.Count; i++)
                {
                    artifactCircles[i].Artifact = weightedCandidateList[i].Key;
                    artifactCircles[i].Circle.Texture = artifactCircles[i].Artifact.Texture;
                }
            }
            numArtifactCircles = i;

            // create the wavy text

            wavyText.Clear();
            WavyText wave;
            for (i = 0; i < numArtifactCircles; i++)
            {
                float angleDeg = (float)(i * 360f / numArtifactCircles);
                angleDeg += 22.5f; // add a tilt so it's more separated into quadrants
                float angleRad = (float)(angleDeg * Math.PI / 180);
                Vector2 direction = WavyText.rotateVector(Vector2.UnitX, angleRad);
                direction.Normalize();
                Vector2 startPos = new Vector2(artifactCircles[CENTER_CIRCLE_ID].Circle.Position.X, artifactCircles[CENTER_CIRCLE_ID].Circle.Position.Y);
                startPos += (artifactCircles[CENTER_CIRCLE_ID].Circle.Radius * 1.3f) * direction;

                float waveHeight = 0.03f;
                string text = artifactCircles[i].Artifact.ArticleName;
                if (maxTextLength > 0 && text.Length > maxTextLength)
                    text = text.Substring(0, maxTextLength - 3) + "...";
                wave = new WavyText(startPos, direction, waveHeight, text, artifactCircles[i].Circle);

                int textLength = text.Length;

                // make some lengths of text appear better on screen by shrinking the font size (DrawScale) and squishing/expanding the space between letters (StretchFactor)
                // DrawScale is absolute value so have to multiply by a percentage, StretchFactor is relative so just assign percentage directly
                if (textLength <= 5)
                {
                    wave.DrawScale *= 1.45f;
                    wave.StretchFactor = 1.25f;
                }
                else if (textLength <= 11)
                {
                    wave.DrawScale *= 1.25f;
                    wave.StretchFactor = 1.15f;
                }
                else if (textLength > 20)
                {
                    wave.DrawScale *= 0.85f;
                    wave.StretchFactor = 0.9f;
                }

                //wave.WaveSpeed = 1f;
                // if between 90 degrees and 270 degrees, flip the text
                if (angleDeg > 90 && angleDeg <= 270)
                    wave.InsideOutText = true;

                wave.resetMovement(); // only need to do if you manually change movement parameters after creating object
                wave.Mode = WavyText.DisplayMode.GrowOutward; // starts by growing outward, will change itself when it hits max
                wavyText.Add(wave);
            }

            // add half very related
            /*
            for (i = 0; i < MAX_CIRCLES / 2 && i < weightedCandidateList.Count; i++)
            {
                artifactCircles[i].Artifact = weightedCandidateList[i].Key;
                artifactCircles[i].Circle.Texture = artifactCircles[i].Artifact.Texture;
            }
            // and half
            Random random = new Random();
            for (; i < MAX_CIRCLES - 1; i++)
            {
                Artifact randomArtifact;
                // make sure the random artifact hasn't already been used
                do
                {
                    randomArtifact = bookshelf.Library.Artifacts[random.Next(bookshelf.Library.Artifacts.Count)];
                } while (candidateList.Contains(randomArtifact) == true);

                artifactCircles[i].Artifact = randomArtifact;
                artifactCircles[i].Circle.Texture = artifactCircles[i].Artifact.Texture;
            }
            numArtifactCircles = MAX_CIRCLES - 1;
            // add 1/4 least related
            // add 1/4 random
            //*/
            PositionRelatedCircles();
        }
        private void library_SelectedArtifactChanged(Artifact selectedArtifact)
        {
            TimelineContainer newContainer = null;
            // change the selected artifact
            foreach (TimelineContainer container in timelineArtifactList)
            {
                if (container.Artifact == selectedArtifact)
                {
                    newContainer = container;
                    break;
                }
            }
            if (newContainer == null)
            {
                return;
            }

            if (selectedContainer != null)
            {
                // deselect the current selected artifact
                selectedContainer.Selected = false;
                selectedContainer.TopCurve.Alpha = ALPHA_RELATED;
                selectedContainer.BottomCurve.Alpha = ALPHA_RELATED;
            }

            // update the selected container
            selectedContainer = newContainer;

            // and change it's status to being selected
            selectedContainer.Selected = true;
            selectedContainer.TopCurve.Alpha = ALPHA_SELECTED;
            selectedContainer.BottomCurve.Alpha = ALPHA_SELECTED;

            // since something was just selected, nothing is highlighted
            highlightedContainer = null;
        }
 private void setImageLocation(Artifact selectedArtifact)
 {
     int w = selectedArtifact.Texture.Width, h = selectedArtifact.Texture.Height;
     if (w > h)
         imageBox = new SelectableQuad(new Vector2(0, 0), new Vector2(w / 512f * maxImageBox.Width, h / 512f * maxImageBox.Height), Color.White);
     else
         imageBox = new SelectableQuad(new Vector2(0, 0), new Vector2(w / 512f * maxImageBox.Width, h / 512f * maxImageBox.Height), Color.White);
 }
        private void library_SelectedArtifactChanged(Artifact selectedArtifact)
        {
            setImageLocation(selectedArtifact);
            imageBox.Texture = selectedArtifact.Texture;

            // decide what gets put in the header, subheader, and body
            // this is the only place you need to make changes if you want to alter what gets displayed in the box
            headerText = selectedArtifact.ArticleName;
            StringBuilder sb = new StringBuilder();
            //subheaderText = "Dates: " + selectedArtifact.CatalogDate.StartYear + ", " + selectedArtifact.ManufactureDate.StartYear + ", " + selectedArtifact.UseDate.StartYear + "\n";
            sb.Append("Catalog #: "); sb.Append(selectedArtifact.CatalogNumber); sb.Append("\n");
            sb.Append("Materials: "); sb.Append(getMaterialString(selectedArtifact.Materials)); sb.Append("\n");

            subheaderText = sb.ToString();

            //subheaderText += "Color: " + selectedArtifact.Color.ToString();

            bodyText = concatenateStrings(new string[] { selectedArtifact.Function, selectedArtifact.CanadianSignificance, selectedArtifact.TechSignificance }, false);

            formatAllText();

            // comment this line out if you don't want the border to change color based on the artifact
            roundedBox.Color = selectedArtifact.Color;
            //bodyColor = selectedArtifact.Color;
        }