public StoreCard(long credits, Part[] storeParts, Part[] humanParts, Part[] robotParts, Color colorScheme, bool enableCreditsSpentAnimation)
    {
        this.credits     = credits;
        this.storeParts  = storeParts;
        this.humanParts  = humanParts;
        this.robotParts  = robotParts;
        this.colorScheme = colorScheme;
        this.enableCreditsSpentAnimation = enableCreditsSpentAnimation;
        mode = MODES.VIEW_PART_STATS;
        partBeingPreviewed            = null;
        partBeingBought               = null;
        currentPartFilter             = DEFAULT_STORE_FILTER;
        STORE_SORT                    = GameObject.Find("StoreSort");
        currentSort                   = DEFAULT_SORT;
        PERFORMANCE_METRIC_CALCULATOR = new PerformanceMetricCalculator();
        SCROLL_VIEW                   = GameObject.Find(STORE_CARD_NAME);
        GameObject storeContainerGameObject = GameObject.Find(STORE_CONTAINER_NAME);

        STORE_CONTAINER = storeContainerGameObject.GetComponent <RectTransform>();
        SCROLL_RECT     = SCROLL_VIEW.GetComponent <ScrollRect>();
        STORE_PANEL     = GameObject.Find(STORE_PANEL_NAME).GetComponent <RectTransform>();
        SCROLLBAR       = GameObject.Find(STORE_CARD_NAME).transform.Find(STORE_SCROLLBAR_NAME).gameObject;
        SCROLLBAR.SetActive(false);
        SCROLL_RECT.vertical = false;
        storeButtons         = new List <GameObject>();
        partInfo             = GameObject.Find("Store").transform.Find(PART_INFO_NAME).gameObject;
        partType             = partInfo.transform.Find(PART_TYPE_NAME).gameObject;
        partStats            = partInfo.transform.Find(PART_STATS_NAME).gameObject;
        partInfo.SetActive(false);
        BUY_PART_BUTTON = GameObject.Find("Store").transform.Find("BuyPart").gameObject;
        BUY_PART_BUTTON.SetActive(false);
        STORE_CREDIT = GameObject.Find("StoreCredit");
        STORE_CREDIT.GetComponent <TextMeshProUGUI>().color = colorScheme;
        updateCredits();
        STORE_CREDITS_SPENT = GameObject.Find("Store").transform.Find("StoreCreditsSpent").gameObject;
        STORE_CREDITS_SPENT_HOME_POSITION = STORE_CREDITS_SPENT.transform.localPosition;
        STORE_CREDITS_SPENT.SetActive(false);
        partStatsList = new List <GameObject>();
        ATTACHMENT_PARTS_ROWS_LABELS = new List <string>();
        foreach (Part part in this.storeParts)
        {
            if (part is Attachment && !ATTACHMENT_PARTS_ROWS_LABELS.Contains(part.GetType().ToString()))
            {
                ATTACHMENT_PARTS_ROWS_LABELS.Add(part.GetType().ToString());
            }
            GameObject storeButton = GameObject.Instantiate(Resources.Load("Prefabs/FeaturedPartButton") as GameObject);
            Texture2D  partIcon    = part.getIcon();
            if (partIcon != null)
            {
                storeButton.transform.Find("Icon").GetComponent <UnityEngine.UI.Image>().sprite = Sprite.Create(partIcon, new Rect(0, 0, partIcon.width, partIcon.height), new Vector2(0.5f, 0.5f), 100);
            }
            storeButton.GetComponent <RectTransform>().localScale = Vector3.one;
            storeButton.transform.localPosition = new Vector3(storeButton.transform.localPosition.x, storeButton.transform.localPosition.y, 0);
            storeButton.transform.Find("CostLabel").GetComponent <TextMeshProUGUI>().text += PERFORMANCE_METRIC_CALCULATOR.calculateCost(part);
            storeButton.transform.Find("CostLabel").GetComponent <TextMeshProUGUI>().color = (PERFORMANCE_METRIC_CALCULATOR.calculateCost(part) <= this.credits ? AFFORDABLE_TEXT_COLOR : UNAFFORDABLE_TEXT_COLOR);
            storeButton.SetActive(false);
            storeButtons.Add(storeButton);
        }
        STORE_TABS = new List <GameObject>();
        foreach (Transform childTransform in GameObject.Find("StoreTabs").transform.Find("StoreTabMask"))
        {
            if (childTransform.gameObject.name.Contains(STORE_TAB_SUFFIX))
            {
                STORE_TABS.Add(childTransform.gameObject);
            }
        }
        FEATURED_PARTS_ROWS = new List <GameObject>();
        foreach (string featuredPartsRowLabel in FEATURED_PARTS_ROWS_LABELS)
        {
            GameObject featuredPartsRow          = GameObject.Instantiate(Resources.Load("Prefabs/FeaturedPartsRow") as GameObject);
            string     featuredPartsRowLabelText = featuredPartsRow.transform.Find("AllParts").Find("Label").gameObject.GetComponent <TextMeshProUGUI>().text;
            featuredPartsRow.transform.Find("AllParts").Find("Label").gameObject.GetComponent <TextMeshProUGUI>().text = featuredPartsRowLabelText.Substring(0, featuredPartsRowLabelText.IndexOf(" ") + 1) + featuredPartsRowLabel + featuredPartsRowLabelText.Substring(featuredPartsRowLabelText.IndexOf(" "));
            featuredPartsRow.transform.localPosition = new Vector3(featuredPartsRow.transform.localPosition.x, featuredPartsRow.transform.localPosition.y, 0);
            featuredPartsRow.SetActive(false);
            FEATURED_PARTS_ROWS.Add(featuredPartsRow);
        }
        ATTACHMENT_PARTS_ROWS = new List <GameObject>();
        foreach (string attachmentPartsRowLabel in ATTACHMENT_PARTS_ROWS_LABELS)
        {
            GameObject attachmentPartsRow          = GameObject.Instantiate(Resources.Load("Prefabs/AttachmentPartsRow") as GameObject);
            string     attachmentPartsRowLabelText = attachmentPartsRow.transform.Find("Label").gameObject.GetComponent <TextMeshProUGUI>().text;
            attachmentPartsRow.transform.Find("Label").gameObject.GetComponent <TextMeshProUGUI>().text = attachmentPartsRowLabel;
            attachmentPartsRow.transform.localPosition = new Vector3(attachmentPartsRow.transform.localPosition.x, attachmentPartsRow.transform.localPosition.y, 0);
            attachmentPartsRow.SetActive(false);
            ATTACHMENT_PARTS_ROWS.Add(attachmentPartsRow);
        }
        filterFeaturedParts();
        updateSorting();
    }
    public void update(long credits, Part[] humanParts, Part[] robotParts, Color colorScheme, bool enableCreditsSpentAnimation)
    {
        this.credits     = credits;
        this.humanParts  = humanParts;
        this.robotParts  = robotParts;
        this.colorScheme = colorScheme;
        this.enableCreditsSpentAnimation = enableCreditsSpentAnimation;
        if (STORE_CREDIT.GetComponent <TextMeshProUGUI>().color != this.colorScheme)
        {
            STORE_CREDIT.GetComponent <TextMeshProUGUI>().color = this.colorScheme;
        }
        if (base.enabled)
        {
            if (BUY_PART_BUTTON.activeSelf && BUY_PART_BUTTON.GetComponent <ButtonListener>().isClicked() && PERFORMANCE_METRIC_CALCULATOR.calculateCost(partBeingPreviewed) <= credits)
            {
                BUY_PART_BUTTON.GetComponent <ButtonListener>().resetClick();
                mode               = MODES.BUY_PART;
                partBeingBought    = partBeingPreviewed;
                partBeingPreviewed = null;
                BUY_PART_BUTTON.SetActive(false);
                credits -= PERFORMANCE_METRIC_CALCULATOR.calculateCost(partBeingBought);
                updateCredits();
                if (enableCreditsSpentAnimation)
                {
                    STORE_CREDITS_SPENT.SetActive(true);
                    STORE_CREDITS_SPENT.transform.localPosition = STORE_CREDITS_SPENT_HOME_POSITION;
                    Color storeCreditsSpentColor = STORE_CREDITS_SPENT.GetComponent <TextMeshProUGUI>().color;
                    STORE_CREDITS_SPENT.GetComponent <TextMeshProUGUI>().color = new Color(storeCreditsSpentColor.r, storeCreditsSpentColor.g, storeCreditsSpentColor.b, 1);
                    STORE_CREDITS_SPENT.GetComponent <TextMeshProUGUI>().text  = "-" + PERFORMANCE_METRIC_CALCULATOR.calculateCost(partBeingBought).ToString();
                }
            }
            if (Input.GetMouseButton(0) && mode == MODES.PREVIEW_PART && !BUY_PART_BUTTON.GetComponent <ButtonListener>().isMouseOver())
            {
                mode = MODES.VIEW_PART_STATS;
                partBeingPreviewed = null;
                partBeingBought    = null;
                BUY_PART_BUTTON.SetActive(false);
            }
            if ((STORE_PANEL.offsetMax.y - STORE_PANEL.offsetMin.y) > (STORE_CONTAINER.offsetMax.y - STORE_CONTAINER.offsetMin.y))
            {
                SCROLLBAR.SetActive(true);
                SCROLL_RECT.vertical = true;
            }
            else
            {
                SCROLLBAR.SetActive(false);
                SCROLL_RECT.vertical = false;
            }
            for (int storeButtonIndex = 0; storeButtonIndex < storeButtons.Count; ++storeButtonIndex)
            {
                ButtonListener buttonListener = storeButtons[storeButtonIndex].GetComponent <ButtonListener>();
                if ((buttonListener.isClicked()) && mode != MODES.PREVIEW_PART)
                {
                    bool ignoreClick = false;
                    foreach (Part part in humanParts)
                    {
                        if (storeParts[storeButtonIndex].getID() == part.getID())
                        {
                            ignoreClick = true;
                            break;
                        }
                    }
                    if (!ignoreClick)
                    {
                        if (buttonListener.isClicked())
                        {
                            mode = MODES.PREVIEW_PART;
                            partInfo.SetActive(false);
                            partBeingPreviewed = storeParts[storeButtonIndex];
                            BUY_PART_BUTTON.SetActive(true);
                            BUY_PART_BUTTON.GetComponent <UnityEngine.UI.Image>().color = (PERFORMANCE_METRIC_CALCULATOR.calculateCost(partBeingPreviewed) <= credits ? colorScheme : UNAFFORDABLE_COLOR);
                        }
                        buttonListener.resetClick();
                        break;
                    }
                    buttonListener.resetClick();
                }
                if (buttonListener.isMouseOver() && mode != MODES.PREVIEW_PART)
                {
                    Part robotPart = null;
                    foreach (Part part in robotParts)
                    {
                        if (part.GetType() == storeParts[storeButtonIndex].GetType())
                        {
                            robotPart = part;
                            break;
                        }
                    }
                    Vector2 position;
                    RectTransformUtility.ScreenPointToLocalPointInRectangle(GameObject.Find("BuildHubCanvas").GetComponent <RectTransform>(), Input.mousePosition, Camera.main, out position);
                    position.x += partInfo.GetComponent <RectTransform>().sizeDelta.x / 2;
                    partInfo.transform.localPosition = position;
                    partType.GetComponent <TextMeshProUGUI>().text = storeParts[storeButtonIndex].GetType().ToString();
                    double[] differenceInStats = robotPart != null?robotPart.compareTo(storeParts[storeButtonIndex]) : (new Blaster("", null, 0, null, Shape.SHAPES.CYLINDER, 0, 0, 0, 0, 0, 0)).compareTo(storeParts[storeButtonIndex]);

                    foreach (GameObject partStat in partStatsList)
                    {
                        GameObject.Destroy(partStat);
                    }
                    partStatsList.Clear();
                    GameObject durabilityPartStat = GameObject.Instantiate(Resources.Load("Prefabs/PartStat") as GameObject);
                    durabilityPartStat.GetComponent <TextMeshProUGUI>().text = "Durability: " + StringTools.formatString(storeParts[storeButtonIndex].getDurability()) + (differenceInStats.Length > 0 ? " (" + applyStatDifferenceFormatting(differenceInStats[1], false) + ")": "");
                    durabilityPartStat.transform.SetParent(partStats.GetComponent <RectTransform>());
                    durabilityPartStat.transform.localPosition = new Vector3(durabilityPartStat.transform.localPosition.x, durabilityPartStat.transform.localPosition.y, 0);
                    partStatsList.Add(durabilityPartStat);
                    string[] partStatStrings = storeParts[storeButtonIndex].getStatStrings();
                    for (int partStatIndex = 0; partStatIndex < partStatStrings.Length; ++partStatIndex)
                    {
                        GameObject partStat = GameObject.Instantiate(Resources.Load("Prefabs/PartStat") as GameObject);
                        string     differenceInStatString = "";
                        int        differenceInStatsIndex = partStatIndex + 2;
                        if (!(storeParts[storeButtonIndex] is Attachment))
                        {
                            differenceInStatString = applyStatDifferenceFormatting(differenceInStats[differenceInStatsIndex], differenceInStatsIndex == 2);
                        }
                        else if (differenceInStats != null && differenceInStats.Length > 0)
                        {
                            if (differenceInStatsIndex == 3 || (differenceInStatsIndex >= 8 && differenceInStatsIndex < 11))
                            {
                                differenceInStatsIndex = -1;
                            }
                            else if (differenceInStatsIndex > 3 && differenceInStatsIndex < 8)
                            {
                                differenceInStatsIndex -= 1;
                            }
                            else if (differenceInStatsIndex == 11)
                            {
                                differenceInStatsIndex -= 4;
                            }
                            if (differenceInStatsIndex != -1)
                            {
                                if (differenceInStatsIndex >= 3 && differenceInStatsIndex <= 6)
                                {
                                    differenceInStats[differenceInStatsIndex] /= 1000;
                                }
                                differenceInStatString = applyStatDifferenceFormatting(differenceInStats[differenceInStatsIndex], differenceInStatsIndex == 2 || differenceInStatsIndex == 3 || differenceInStatsIndex == 4 || differenceInStatsIndex == 6);
                            }
                        }
                        partStat.GetComponent <TextMeshProUGUI>().text = partStatStrings[partStatIndex] + (differenceInStatString != "" ? " (" + differenceInStatString + ")" : "");
                        partStat.transform.SetParent(partStats.GetComponent <RectTransform>());
                        partStat.transform.localPosition = new Vector3(partStat.transform.localPosition.x, partStat.transform.localPosition.y, 0);
                        partStatsList.Add(partStat);
                    }
                    partInfo.SetActive(true);
                    break;
                }
                else
                {
                    partInfo.SetActive(false);
                }
            }
            bool switchTabs = false;
            foreach (GameObject tab in STORE_TABS)
            {
                if (tab.GetComponent <ButtonListener>().isClicked() && currentPartFilter != tab.transform.Find("Label").gameObject.GetComponent <TextMeshProUGUI>().text)
                {
                    switchTabs = true;
                    filterParts(tab.transform.Find("Label").gameObject.GetComponent <TextMeshProUGUI>().text);
                    updateSorting();
                    break;
                }
                else
                {
                    tab.GetComponent <ButtonListener>().resetClick();
                }
            }
            foreach (GameObject featuredPartsRow in FEATURED_PARTS_ROWS)
            {
                if (featuredPartsRow.GetComponent <ButtonListener>().isClicked())
                {
                    switchTabs = true;
                    string allPartsButtonLabelText = featuredPartsRow.transform.Find("AllParts").Find("Label").gameObject.GetComponent <TextMeshProUGUI>().text;
                    foreach (GameObject tab in STORE_TABS)
                    {
                        if (allPartsButtonLabelText.Contains(tab.transform.Find("Label").gameObject.GetComponent <TextMeshProUGUI>().text))
                        {
                            tab.GetComponent <ButtonListener>().click();
                            break;
                        }
                    }
                    featuredPartsRow.GetComponent <ButtonListener>().resetClick();
                    filterParts(allPartsButtonLabelText.Substring(allPartsButtonLabelText.IndexOf(" ") + 1, allPartsButtonLabelText.LastIndexOf(" ") - (allPartsButtonLabelText.IndexOf(" ") + 1) - 1));
                    updateSorting();
                    break;
                }
                else
                {
                    featuredPartsRow.GetComponent <ButtonListener>().resetClick();
                }
            }
            if (switchTabs)
            {
                foreach (GameObject tab in STORE_TABS)
                {
                    if (tab.GetComponent <ButtonListener>().isClicked())
                    {
                        tab.GetComponent <ButtonListener>().resetClick();
                        tab.GetComponent <UnityEngine.UI.Image>().color = ACTIVE_TAB_COLOR;
                    }
                    else
                    {
                        tab.GetComponent <UnityEngine.UI.Image>().color = INACTIVE_TAB_COLOR;
                    }
                }
            }
            if (currentSort != STORE_SORT.GetComponent <TMP_Dropdown>().value)
            {
                currentSort = STORE_SORT.GetComponent <TMP_Dropdown>().value;
                applySorting();
            }
            if (enableCreditsSpentAnimation && STORE_CREDITS_SPENT.activeSelf)
            {
                Vector3 position = STORE_CREDITS_SPENT.transform.localPosition;
                STORE_CREDITS_SPENT.transform.localPosition = new Vector3(position.x, position.y + STORE_CREDITS_SPENT_ANIMATION_POSITION_SPEED, position.z);
                Color storeCreditsSpentColor = STORE_CREDITS_SPENT.GetComponent <TextMeshProUGUI>().color;
                STORE_CREDITS_SPENT.GetComponent <TextMeshProUGUI>().color = new Color(storeCreditsSpentColor.r, storeCreditsSpentColor.g, storeCreditsSpentColor.b, storeCreditsSpentColor.a - STORE_CREDITS_SPENT_ANIMATION_COLOR_SPEED);
                if (STORE_CREDITS_SPENT.GetComponent <TextMeshProUGUI>().color.a <= 0)
                {
                    STORE_CREDITS_SPENT.SetActive(false);
                }
            }
            else
            {
                if (STORE_CREDITS_SPENT.transform.localPosition != STORE_CREDITS_SPENT_HOME_POSITION)
                {
                    STORE_CREDITS_SPENT.transform.localPosition = STORE_CREDITS_SPENT_HOME_POSITION;
                }
                Color storeCreditsSpentColor = STORE_CREDITS_SPENT.GetComponent <TextMeshProUGUI>().color;
                if (STORE_CREDITS_SPENT.GetComponent <TextMeshProUGUI>().color.a != 1)
                {
                    STORE_CREDITS_SPENT.GetComponent <TextMeshProUGUI>().color = new Color(storeCreditsSpentColor.r, storeCreditsSpentColor.g, storeCreditsSpentColor.b, 1);
                }
                if (STORE_CREDITS_SPENT.activeInHierarchy)
                {
                    STORE_CREDITS_SPENT.SetActive(false);
                }
            }
        }
    }