// Use this for initialization
    void Awake()
    {
        testingPoints = new Dictionary<EDSAC.TestingPointsType,GameObject>{
            { EDSAC.TestingPointsType.TYPE1, prefabTP1 },
            { EDSAC.TestingPointsType.TYPE2, prefabTP2 },
            { EDSAC.TestingPointsType.TYPE3, prefabTP3 },
            { EDSAC.TestingPointsType.TYPE4, prefabTP4} };

        valves = new Dictionary<EDSAC.ValveType,GameObject>{
            { EDSAC.ValveType.BIG_SHINY, prefabValveBigShiny},
            { EDSAC.ValveType.BIG_FLAT, prefabValveBigFlat},
            { EDSAC.ValveType.SMALL_BLACK, prefabValveSmallBlack},
            { EDSAC.ValveType.SMALL_CREAM, prefabValveSmallCream},
            { EDSAC.ValveType.SMALL_RED, prefabValveSmallRed} };

        edsac = populater.Populate();

        labelTargetsHolder = new GameObject();
        labelTargetsHolder.transform.SetParent(transform);
        labelTargetsHolder.transform.name = "Label Targets";

        if (edsac.rows.ContainsKey(EDSAC.RowName.REAR)) {
            FillRow(rearRacks, edsac.rows[EDSAC.RowName.REAR]);
        }
        if (edsac.rows.ContainsKey(EDSAC.RowName.MIDDLE)) {
            FillRow(middleRacks, edsac.rows[EDSAC.RowName.MIDDLE]);
        }
        if (edsac.rows.ContainsKey(EDSAC.RowName.FRONT)) {
            FillRow(frontRacks, edsac.rows[EDSAC.RowName.FRONT]);
        }
        FillWires();

        Destroy(this);
    }
 // Use this for initialization
 public EDSAC Populate()
 {
     edsac = new EDSAC();
     reader = new TinyXmlReader(edsacXml.text);
     string readingDebugText = "Debug output from XML population:\n\n";
     while (reader.Read()) {
         if (reader.isOpeningTag) {
             if (reader.tagName == "chassisdefinition") {
                 readingDebugText += "New chassis definition found.\n";
                 EDSAC.ChassisType c = new EDSAC.ChassisType();
                 string key = "";
                 while (reader.tagName != "chassisdefinition" || reader.isOpeningTag) {
                     reader.Read();
                     if (reader.isOpeningTag) {
                         switch(reader.tagName) {
                         case "chassistype":
                             key = reader.content;
                             readingDebugText += "Chassis definition key: " + key + "\n";
                             break;
                         case "testingpoints":
                             switch (reader.content) {
                             case "1":
                                 c.testingPoints = EDSAC.TestingPointsType.TYPE1;
                                 break;
                             case "2":
                                 c.testingPoints = EDSAC.TestingPointsType.TYPE2;
                                 break;
                             case "3":
                                 c.testingPoints = EDSAC.TestingPointsType.TYPE3;
                                 break;
                             case "4":
                                 c.testingPoints = EDSAC.TestingPointsType.TYPE4;
                                 break;
                             }
                             readingDebugText += "Chassis testing points: " + c.testingPoints.ToString() + "\n";
                             break;
                         case "valve":
                             EDSAC.Valve v = new EDSAC.Valve();
                             readingDebugText += "New valve.\n";
                             while (reader.tagName != "valve" || reader.isOpeningTag) {
                                 reader.Read();
                                 if (reader.isOpeningTag) {
                                     switch(reader.tagName) {
                                     case "valvetype":
                                         switch (reader.content) {
                                         case "SmallRed":
                                             v.valveType = EDSAC.ValveType.SMALL_RED;
                                             break;
                                         case "SmallCream":
                                             v.valveType = EDSAC.ValveType.SMALL_CREAM;
                                             break;
                                         case "SmallBlack":
                                             v.valveType = EDSAC.ValveType.SMALL_BLACK;
                                             break;
                                         case "BigFlat":
                                             v.valveType = EDSAC.ValveType.BIG_FLAT;
                                             break;
                                         case "BigShiny":
                                             v.valveType = EDSAC.ValveType.BIG_SHINY;
                                             break;
                                         }
                                         readingDebugText += "Valve type: " + v.valveType.ToString() + "\n";
                                         break;
                                     case "valvex":
                                         v.x = float.Parse(reader.content);
                                         readingDebugText += "Valve x: " + v.x + "\n";
                                         break;
                                     case "valvey":
                                         v.y = float.Parse(reader.content);
                                         readingDebugText += "Valve y: " + v.y + "\n";
                                         break;
                                     }
                                 }
                             }
                             c.valves.Add (v);
                             break;
                         }
                     }
                 }
                 edsac.availableChassisTypes.Add(key, c);
             } else if (reader.tagName == "row") {
                 readingDebugText += "New row found.\n";
                 EDSAC.RowName rowName = EDSAC.RowName.UNKNOWN;
                 while (reader.tagName != "row" || reader.isOpeningTag) {
                     reader.Read();
                     if (reader.isOpeningTag) {
                         switch(reader.tagName) {
                         case "rowname":
                             switch(reader.content) {
                             case "Rear":
                                 rowName = EDSAC.RowName.REAR;
                                 break;
                             case "Middle":
                                 rowName = EDSAC.RowName.MIDDLE;
                                 break;
                             case "Front":
                                 rowName = EDSAC.RowName.FRONT;
                                 break;
                             }
                             readingDebugText += "Row type: " + rowName.ToString() + "\n";
                             break;
                         case "rack":
                             EDSAC.Rack r = new EDSAC.Rack();
                             readingDebugText += "New rack found.\n";
                             while (reader.tagName != "rack" || reader.isOpeningTag) {
                                 reader.Read();
                                 if (reader.isOpeningTag) {
                                     switch(reader.tagName) {
                                     case "racknumber":
                                         r.rackNumber = int.Parse(reader.content);
                                         readingDebugText += "Rack number: " + r.rackNumber + "\n";
                                         break;
                                     case "chassis":
                                         readingDebugText += "New chassis found.\n";
                                         EDSAC.Chassis c = new EDSAC.Chassis();
                                         while (reader.tagName != "chassis" || reader.isOpeningTag) {
                                             reader.Read();
                                             if (reader.isOpeningTag) {
                                                 switch(reader.tagName) {
                                                 case "chassisnumber":
                                                     c.chassisNumber = int.Parse(reader.content);
                                                     readingDebugText += "Chassis number: " + c.chassisNumber + "\n";
                                                     break;
                                                 case "chassisworldlabeltext":
                                                     c.physicalLabelNameText = reader.content;
                                                     readingDebugText += "Chassis label text: " + c.physicalLabelNameText + "\n";
                                                     break;
                                                 case "chassisworldlabelnumber":
                                                     c.physicalLabelNumberText = reader.content;
                                                     readingDebugText += "Chassis label number: " + c.physicalLabelNumberText + "\n";
                                                     break;
                                                 case "chassisuilabel":
                                                     c.uiLabelText = reader.content;
                                                     readingDebugText += "Chassis UI label: " + c.uiLabelText + "\n";
                                                     break;
                                                 case "chassistype":
                                                     if (edsac.availableChassisTypes.ContainsKey(reader.content)) {
                                                         c.chassisType = edsac.availableChassisTypes[reader.content];
                                                     } else {
                                                         c.chassisType = new EDSAC.ChassisType();
                                                     }
                                                     readingDebugText += "Chassis type: " + reader.content + "\n";
                                                     break;
                                                 }
                                             }
                                         }
                                         r.chassis.Add(c);
                                         break;
                                     }
                                 }
                             }
                             edsac.rows[rowName].racks.Add(r);
                             break;
                         }
                     }
                 }
             }
         }
     }
     Debug.Log (readingDebugText);
     return edsac;
 }
    public void FillRow(GameObject[] physicalRow, EDSAC.Row infoRow)
    {
        EDSAC.Row ro = infoRow;
        GameObject[] theseRacks = physicalRow;
        foreach (EDSAC.Rack ra in ro.racks) {
            if (ra.rackNumber <= theseRacks.Length && ra.rackNumber > 0) {
                GameObject prefabRack = theseRacks[ra.rackNumber-1];
                GameObject rackLabelsHolder = Instantiate(prefabWithRectTransform) as GameObject;
                rackLabelsHolder.transform.SetParent(labelsHolder.transform,false);
                switch(ro.name) {
                case EDSAC.RowName.REAR:
                    rackLabelsHolder.transform.name = "R" + ra.rackNumber;
                    break;
                case EDSAC.RowName.MIDDLE:
                    rackLabelsHolder.transform.name = "M" + ra.rackNumber;
                    break;
                case EDSAC.RowName.FRONT:
                    rackLabelsHolder.transform.name = "F" + ra.rackNumber;
                    break;
                }
                foreach (EDSAC.Chassis ch in ra.chassis) {
                    int i = ch.chassisNumber-1;
                    if (i >= 0 && i < 14) {

                        GameObject chassis = Instantiate(prefabChassis) as GameObject;
                        chassis.transform.parent = prefabRack.transform;
                        chassis.transform.localScale = new Vector3 (1f, 1f, 1f);
                        chassis.transform.localPosition = new Vector3 (0f,
                                                                       chassis_start_y+i*chassis_delta_y,
                                                                       chassis_offset_z);
                        if (ch.physicalLabelNameText != "" || ch.physicalLabelNumberText != "") {
                            GameObject chassisLabel = Instantiate(prefabChassisLabel) as GameObject;
                            chassisLabel.transform.SetParent(chassis.transform,false);
                            foreach (TextMesh t in chassisLabel.GetComponentsInChildren<TextMesh>()) {
                                if (t.gameObject.name == "Chassis Name") {
                                    t.text = ch.physicalLabelNameText;
                                } else if (t.gameObject.name == "Chassis Number") {
                                    t.text = ch.physicalLabelNumberText;
                                }
                            }
                        }

                        GameObject uiLabel = Instantiate (prefabUILabel) as GameObject;
                        uiLabel.transform.SetParent(rackLabelsHolder.transform);
                        uiLabel.transform.localScale = new Vector3(.8f,.8f,1f);
                        uiLabel.transform.name = ch.uiLabelText + " Label";
                        GameObject uiLabelTarget = Instantiate(prefabUILabelTarget) as GameObject;
                        uiLabelTarget.transform.SetParent(labelTargetsHolder.transform);
                        uiLabelTarget.transform.name = ch.uiLabelText + " Label Target";

                        LabelController labelController = uiLabel.GetComponent<LabelController>();
                        labelController.viewCamera = viewCamera;
                        labelController.targetForLabel = uiLabelTarget.GetComponent<Renderer>();

                        labelController.oneAlphaDistance = labelOneAlphaDistance;
                        labelController.zeroAlphaDistance = labelZeroAlphaDistance;
                        labelController.minAlpha = labelMinAlpha;
                        labelController.considerNormal = labelConsiderNormal;
                        labelController.normalInfluence = labelNormalInfluence;
                        labelController.power = labelPower;

                        Text uiLabelText = uiLabel.GetComponentInChildren<Text>();
                        uiLabelText.text = ch.uiLabelText;
                        while (uiLabelText.preferredWidth > 200f && uiLabelText.fontSize > 10)
                            uiLabelText.fontSize--;
                        ((RectTransform)uiLabelText.transform).sizeDelta = new Vector2(uiLabelText.preferredWidth, 30f);

                        uiLabelTarget.GetComponent<LabelAlignmentOnChassis>().chassis = chassis.transform;

                        if (testingPoints.ContainsKey(ch.chassisType.testingPoints)) {
                            GameObject tpChosen = testingPoints[ch.chassisType.testingPoints];
                            GameObject tp = Instantiate(tpChosen) as GameObject;

                            tp.transform.parent = chassis.transform;
                            tp.transform.localScale = new Vector3 (1f, 1f, 1f);
                            tp.transform.localPosition = new Vector3 (0f, testing_pt_offset_y, testing_pt_offset_z);
                        }
                        if (ch.chassisType.valves.Count > 0) {
                            foreach (EDSAC.Valve v in ch.chassisType.valves) {
                                if (valves.ContainsKey(v.valveType)) {
                                    GameObject valveChosen = valves[v.valveType];
                                    GameObject valve = Instantiate(valveChosen) as GameObject;

                                    valve.transform.parent = chassis.transform;
                                    valve.transform.localScale = new Vector3 (1f, 1f, 1f);
                                    valve.transform.rotation *= Quaternion.Euler(0f, 180f, 0f);
                                    valve.transform.localPosition = new Vector3 (
                                        v.x,
                                        valve_offset_y,
                                        v.y);
                                }
                            }
                        } else if (!edsac.availableChassisTypes.ContainsValue(ch.chassisType)) {
                            // make it up!

                            // probabilities of randomly skipping bits
                            float prob_valve = 0.9f;

                            // for placing the two rows of valves
                            float valve_start_x = 0.34f;
                            float valve_delta_x = 0.052f;
                            float valve_offset_y = -0.0019f;
                            float valve_back_row_z = 0.006f;
                            float valve_front_row_z = 0.055f;

                            int bigValvesCount = 2;
                            EDSAC.ValveType[] bigValves = new EDSAC.ValveType[] { EDSAC.ValveType.BIG_FLAT, EDSAC.ValveType.BIG_SHINY };
                            EDSAC.ValveType[] smallValves = new EDSAC.ValveType[] { EDSAC.ValveType.SMALL_BLACK, EDSAC.ValveType.SMALL_CREAM, EDSAC.ValveType.SMALL_RED };
                            int smallValvesCount = 3;
                            int idx;
                            // for each chassis, make big valves
                            for (int j = 0; j < 14; j++) {

                                idx = (int) (Random.value * bigValvesCount);
                                GameObject valveChosen = valves[bigValves[idx]];
                                GameObject valve = Instantiate(valveChosen) as GameObject;

                                valve.transform.parent = chassis.transform;
                                valve.transform.localScale = new Vector3 (1, 1, 1);
                                valve.transform.rotation *= Quaternion.Euler(0, 180, 0);
                                valve.transform.localPosition = new Vector3 (
                                    valve_start_x-valve_delta_x*j,
                                    valve_offset_y,
                                    (j==1 || j==12) ? valve_front_row_z : valve_back_row_z);
                            }

                            // for each chassis, make small valves
                            for (int j = 0; j < 9; j++) {

                                if (Random.value > prob_valve) continue;

                                idx = (int) (Random.value * smallValvesCount);
                                GameObject valveChosen = valves[smallValves[idx]];
                                GameObject valve = Instantiate(valveChosen) as GameObject;

                                valve.transform.parent = chassis.transform;
                                valve.transform.localScale = new Vector3 (1, 1, 1);
                                valve.transform.rotation *= Quaternion.Euler(0, 180, 0);
                                valve.transform.localPosition = new Vector3 (
                                    valve_start_x-valve_delta_x*(j+2.5f),
                                    valve_offset_y,
                                    valve_front_row_z);
                            }
                        }
                    }
                }
            }
        }
    }