/// <summary>
    /// Gets the cell to be displayed. You can have numerous cell types, allowing variety in your list.
    /// Some examples of this would be headers, footers, and other grouping cells.
    /// </summary>
    /// <param name="scroller">The scroller requesting the cell</param>
    /// <param name="dataIndex">The index of the data that the scroller is requesting</param>
    /// <param name="cellIndex">The index of the list. This will likely be different from the dataIndex if the scroller is looping</param>
    /// <returns>The cell for the scroller to use</returns>
    public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex)
    {
        // first, we get a cell from the scroller by passing a prefab.
        // if the scroller finds one it can recycle it will do so, otherwise
        // it will create a new cell.
        DayScrollItemView cellView = scroller.GetCellView(cellViewPrefab) as DayScrollItemView;

        // set the name of the game object to the cell's data index.
        // this is optional, but it helps up debug the objects in
        // the scene hierarchy.
        cellView.name = "Cell " + dataIndex.ToString();

        // in this example, we just pass the data to our cell's view which will update its UI
        DateTime  firstDate = _data[0].date;
        GraphData graphData = _data[dataIndex];

        // define what data to provide
        if (appMode == AppMode.SAA)
        {
            if (_graphView == GraphView.Weekly)
            {
                // Debug.Log($"data date: {data.date}, firstDate: {firstDate}");
                // show week text only for the 1st day of the week (Sunday)
                if (graphData.date.DayOfWeek == DayOfWeek.Sunday)
                {
                    // check num of week
                    int numOfWeek = Mathf.FloorToInt(graphData.date.Subtract(firstDate).Days / 7f) + 1;

                    DateTime periodEndDate = graphData.date.AddDays(7);

                    cellView.SetData(graphData, false, null, numOfWeek,
                                     new StringBuilder(graphData.date.FormatToDateMonth()).Append("-")
                                     .Append(periodEndDate.FormatToDateMonth())
                                     .ToString());
                }
                else
                {
                    cellView.SetData(graphData, false);
                }
            }
            else if (_graphView == GraphView.Monthly)
            {
                // show month only for the 1st day of the month
                if (graphData.date.Day == 1)
                {
                    // check what week range does this month it include
                    int daysToMonthStart = graphData.date.Subtract(firstDate).Days;
                    int daysToMonthEnd   = graphData.date.EndOfMonth().Subtract(firstDate).Days;

                    int           startNumOfWeek = Mathf.FloorToInt(daysToMonthStart / 7f) + 1;
                    int           endNumOfWeek   = Mathf.FloorToInt(daysToMonthEnd / 7f) + 1;
                    StringBuilder sb             = new StringBuilder("WEEK ").Append(startNumOfWeek).Append(" - WEEK ").Append(endNumOfWeek);

                    cellView.SetData(graphData, false, new [] { graphData.date.ToString("MMM").ToUpper(), sb.ToString() });
                }
                else
                {
                    cellView.SetData(graphData, false);
                }
            }
        }
        else
        {
            cellView.SetData(graphData, true);
        }

        // return the cell to the scroller
        return(cellView);
    }
    private void ScrollerScrolled(EnhancedScroller enhancedScroller, Vector2 val, float scrollposition)
    {
        int currentActiveCellIndex = scroller.GetClosestCellIndex();

        // Debug.Log($"ScrollerScrolled. _lastActiveCellIndex: {_lastActiveCellIndex}, currentActiveCellIndex: {currentActiveCellIndex}, total data count: {_data.Count}");

        // check is start and end cell items indexes are in a range of 7 days and value not equals to previously cached value
        if (_lastActiveCellIndex != currentActiveCellIndex && currentActiveCellIndex > -1 &&
            currentActiveCellIndex < _data.Count)
        {
            _lastActiveCellIndex = currentActiveCellIndex;

            EnhancedScrollerCellView activeCell = scroller.GetClosestCellView();

            if (activeCell != null)
            {
                // set focus of cells only for daily view in CSU mode
                if (appMode == AppMode.CSU)
                {
                    if (activeCell != null)
                    {
                        _lastActiveCellView?.SetFocus(false);

                        _lastActiveCellView = (activeCell as DayScrollItemView);
                        // Debug.Log(
                        // $"active cell data: {_lastActiveCellView.graphData.data}, date: {_lastActiveCellView.graphData.date}, value: {_lastActiveCellView.graphData.interpolatedScore}");
                        _lastActiveCellView.SetFocus(true);
                    }
                }
            }
        }

        QuestionBasedTrackerData data = _data[_lastActiveCellIndex].data;

        // for CSU
        if (_trackerType == TrackerManager.TrackerType.CSU)
        {
            // Debug.Log("data: " + data);

            // hide by default
            _photoHint.UpdateValue(null);

            if (data != null)
            {
                // if there are some photos
                int numOfPhotos = (data as CSUData).GetPhotosCount();
                // Debug.Log("Photos count: " + numOfPhotos);
                if (numOfPhotos > 0)
                {
                    _photoHint.UpdateValue(numOfPhotos.ToString());
                }
            }

            _CSUViewController.UpdateData(data as CSUData);
        }
        // if using the graph (3 of 4 trackers)
        else
        {
            // move graph camera together with a slider
            _graphController.UpdateCameraView(val.x);

            // set score
            _scoreHint.UpdateValue(data == null ? string.Empty : data.GetScore().ToString());
        }

        // cache last scroll position to restore last position on screen Hide >> Show or tracker type change
        if (_scrollLastPositions.ContainsKey(_trackerType))
        {
            _scrollLastPositions[_trackerType] = val.x;
        }
        else
        {
            _scrollLastPositions.Add(_trackerType, val.x);
        }

        // check notes
        if (_lastActiveCellIndex > -1)
        {
            List <NoteData> notes = NotesManager.GetNoteData(_data[_lastActiveCellIndex].date);
            if (notes.Count > 0)
            {
                _notesHint.UpdateValue(notes.Count.ToString());
            }
            else
            {
                _notesHint.UpdateValue(null);
            }
        }
        else
        {
            _notesHint.UpdateValue(null);
        }
    }