// Calculate x-coordinates for actors
        private void SpecifyPositions(List <int> actorsIndices, ActorScreenPositionType regionType)
        {
            float regionLeft = GetRegionLeft(regionType), regionRight = GetRegionRight(regionType);
            float left = regionLeft, right = regionLeft;
            int   leftIndex = 0, rightIndex = 0;

            for (int i = 0; i <= actorsIndices.Count; i++)
            {
                if (i == actorsIndices.Count)
                {
                    rightIndex = actorsIndices.Count;
                    right      = regionRight;
                }
                if (rightIndex > leftIndex)
                {
                    float actorRegionWidth = (right - left) / (rightIndex - leftIndex);
                    // find positions for actors from leftIndex (including) to rightIndex (not including)
                    for (int j = leftIndex; j < rightIndex; j++)
                    {
                        _allActors[actorsIndices[j]].Position.x = left + actorRegionWidth * (j + 0.5f);
                    }
                    leftIndex = rightIndex + 1;
                }
            }
        }
        // Consider which actors are new and which must be removed
        private void PrepareActors(List <ActorState> actorStates, out bool mustChangeArrangement)
        {
            _removedActorsIndices.Clear();

            mustChangeArrangement = false;
            foreach (var actorState in actorStates)
            {
                if (!Field.FieldExists(actorState.fields, ActorArrangementActionFieldName))
                {
                    continue;
                }
                string actionTypeString = Field.LookupValue(actorState.fields, ActorArrangementActionFieldName);
                ActorArrangementActionType actionType = (ActorArrangementActionType)Enum.Parse(typeof(ActorArrangementActionType), actionTypeString);

                // Manage actor infos
                switch (actionType)
                {
                case ActorArrangementActionType.None:
                    break;

                case ActorArrangementActionType.ChangePosition:
                    if (!_actorIdToIndex.ContainsKey(actorState.ActorID))
                    {
                        AddActor(actorState.ActorID);
                        mustChangeArrangement = true;
                    }
                    Assert.IsTrue(_actorIdToIndex.ContainsKey(actorState.ActorID), "Arrangement with type 'changePosition' is applied to the absent actor");
                    ActorInfo actorInfo = _allActors[_actorIdToIndex[actorState.ActorID]];
                    Assert.IsTrue(Field.FieldExists(actorState.fields, PositionTypeFieldName), "Actor state doesn't have Position Type field when it's needed");
                    string positionTypeString            = Field.LookupValue(actorState.fields, PositionTypeFieldName);
                    ActorScreenPositionType positionType = (ActorScreenPositionType)Enum.Parse(typeof(ActorScreenPositionType), positionTypeString);
                    if (actorInfo.PositionType != positionType)
                    {
                        mustChangeArrangement = true;
                    }
                    // Update actorInfo
                    actorInfo.PositionType = positionType;
                    break;

                case ActorArrangementActionType.Leave:
                    DeleteActor(actorState.ActorID);
                    mustChangeArrangement = true;
                    break;

                default:
                    Assert.IsTrue(false);
                    break;
                }
            }
        }
        // Right boundary of screen region
        private float GetRegionRight(ActorScreenPositionType regionType)
        {
            switch (regionType)
            {
            case ActorScreenPositionType.Left:
                return(GetCenterLeft());

            case ActorScreenPositionType.Center:
                return(GetCenterRight());

            case ActorScreenPositionType.Right:
                return(_boundaries.xMax);

            default:
                Assert.IsTrue(false);
                return(0f);
            }
        }
        // Get default x-coordinate for positionType
        private float GetDefaultPosition(ActorScreenPositionType positionType)
        {
            switch (positionType)
            {
            case ActorScreenPositionType.Left:
                return(_boundaries.xMin);

            case ActorScreenPositionType.Center:
                return((_boundaries.xMax + _boundaries.xMin) / 2);

            case ActorScreenPositionType.Right:
                return(_boundaries.xMax);

            default:
                Assert.IsTrue(false);
                return(0f);
            }
        }