/*public void CalculateLayout(Scheme layout, double height, Dictionary<int, CableSymbol> cableSymbolById, Dictionary<int, CableInfo> cableInfoById, E3Text text)
         * {
         *  SortSymbols();
         *  cableLayoutById = new Dictionary<int, CableLayout>(cableIds.Count);
         *  foreach (DeviceSymbol deviceSymbol in deviceSymbols)
         *  {
         *      deviceSymbol.CalculateLayout(height);
         *      foreach (SymbolPin topPin in deviceSymbol.TopPins)
         *          foreach (int cableId in topPin.CableIds)
         *          {
         *              if (!cableLayoutById.ContainsKey(cableId))
         *                  cableLayoutById.Add(cableId, new CableLayout(cableId, Level.Top));
         *              cableLayoutById[cableId].AddOffset(new Point(width + topPin.HorizontalOffset, height));
         *          }
         *      foreach (SymbolPin bottomPin in deviceSymbol.BottomPins)
         *          foreach (int cableId in bottomPin.CableIds)
         *          {
         *              if (!cableLayoutById.ContainsKey(cableId))
         *                  cableLayoutById.Add(cableId, new CableLayout(cableId, Level.Bottom));
         *              cableLayoutById[cableId].AddOffset(new Point(width + bottomPin.HorizontalOffset, 0));
         *          }
         *      width += deviceSymbol.Size.Width;
         *  }
         *  matePositionByCableId = layout.GetMatePositionByCableId(Id);
         *  groupPosition = layout.GetGroupPosition(Id);
         *  AdjustCableLayouts(cableLayoutById, cableSymbolById, cableInfoById);
         *  assignmentWidth = text.GetTextLength("Шкаф " + assignment, new E3Font(height: 3));
         *  TopMargin = height + gridStep * 2 + (topCableVerticalOffsetByStep.Count > 0 ? (topCableVerticalOffsetByStep.Last().Value - height) : 0);
         *  BottomMargin = ((bottomCableVerticalOffsetByStep.Count > 0) ? bottomCableVerticalOffsetByStep.Last().Value : 0) + gridStep;
         *  double additionalAssignmentMargin = (width > assignmentWidth) ? gridStep : (assignmentWidth - width + gridStep / 2);
         *  double minCablesOffset = cableLayoutById.Values.Min(cl=>cl.MinOffset);
         *  LeftMargin = ((minCablesOffset > 0) ? 0 : -minCablesOffset) + additionalAssignmentMargin;
         *  double maxCablesOffset = cableLayoutById.Values.Max(cl => cl.MaxOffset);
         *  RightMargin = ((width > maxCablesOffset) ? width : maxCablesOffset) + additionalAssignmentMargin;
         * }*/

        public void CalculateLayout(SymbolScheme scheme, double height, Dictionary <int, CableSymbol> cableSymbolById, Dictionary <int, CableInfo> cableInfoById, E3Text text)
        {
            SortSymbols();
            cableLayoutById = new Dictionary <int, CableLayout>(cableIds.Count);
            foreach (DeviceSymbol deviceSymbol in deviceSymbols)
            {
                deviceSymbol.CalculateLayout(height);
                foreach (SymbolPin topPin in deviceSymbol.TopPins)
                {
                    foreach (int cableId in topPin.CableIds)
                    {
                        if (!cableLayoutById.ContainsKey(cableId))
                        {
                            cableLayoutById.Add(cableId, new CableLayout(cableId, Level.Top));
                        }
                        cableLayoutById[cableId].AddOffset(new Point(width + topPin.HorizontalOffset, height));
                    }
                }
                foreach (SymbolPin bottomPin in deviceSymbol.BottomPins)
                {
                    foreach (int cableId in bottomPin.CableIds)
                    {
                        if (!cableLayoutById.ContainsKey(cableId))
                        {
                            cableLayoutById.Add(cableId, new CableLayout(cableId, Level.Bottom));
                        }
                        cableLayoutById[cableId].AddOffset(new Point(width + bottomPin.HorizontalOffset, 0));
                    }
                }
                width += deviceSymbol.Size.Width;
            }
            matePositionByCableId = scheme.GetMatePositionByCableId(Id);
            groupPosition         = scheme.GetGroupPosition(Id);
            AdjustCableLayouts(cableLayoutById, cableSymbolById, cableInfoById);
            assignmentWidth = text.GetTextLength("Шкаф " + assignment, new E3Font(height: 3));
            TopMargin       = height + gridStep * 2 + (topCableVerticalOffsetByStep.Count > 0 ? (topCableVerticalOffsetByStep.Last().Value - height) : 0);
            BottomMargin    = ((bottomCableVerticalOffsetByStep.Count > 0) ? bottomCableVerticalOffsetByStep.Last().Value : 0) + gridStep;
            double additionalAssignmentMargin = (width > assignmentWidth) ? gridStep : (assignmentWidth - width + gridStep / 2);
            double minCablesOffset            = cableLayoutById.Values.Min(cl => cl.MinOffset);

            LeftMargin = ((minCablesOffset > 0) ? 0 : -minCablesOffset) + additionalAssignmentMargin;
            double maxCablesOffset = cableLayoutById.Values.Max(cl => cl.MaxOffset);

            RightMargin = ((width > maxCablesOffset) ? width : maxCablesOffset) + additionalAssignmentMargin;
        }
        /*private Scheme layout;
         *
         * public Size Size
         * {
         *  get
         *  {
         *      return layout.Size;
         *  }
         * }*/

        public static List <SymbolScheme> GetSchemesForConnection(IEnumerable <int> connectedDeviceIds, Dictionary <int, DeviceSymbol> deviceSymbolById, Dictionary <int, CableInfo> cableInfoById, E3Text text)
        {
            Dictionary <int, DeviceGroup> deviceGroupById         = GetGroupById(connectedDeviceIds, deviceSymbolById, cableInfoById);
            Dictionary <int, List <int> > deviceGroupIdsByCableId = GetDeviceGroupIdsByCableId(cableInfoById.Count, deviceGroupById.Values);
            string connectingBoxAssignment = "AssignmentForConnectingBox";
            Dictionary <string, List <DeviceGroup> > deviceGroupsByAssignment = GetDeviceGroupsByAssignment(deviceGroupById, connectingBoxAssignment);
            int schemeSymbolId          = deviceGroupById.Count;
            List <SymbolScheme> schemes = new List <SymbolScheme>(deviceGroupsByAssignment.Count);

            foreach (string assignment in deviceGroupsByAssignment.Keys)
            {
                Dictionary <int, ISchemeSymbol> symbolById         = new Dictionary <int, ISchemeSymbol>();
                Dictionary <int, List <int> >   symbolIdsByCableId = new Dictionary <int, List <int> >();
                List <DeviceGroup> deviceGroups = deviceGroupsByAssignment[assignment];
                foreach (DeviceGroup deviceGroup in deviceGroups)
                {
                    AddConnectedSchemeSymbols(deviceGroup, symbolById, symbolIdsByCableId, deviceGroupIdsByCableId, deviceGroupById, connectingBoxAssignment, assignment, ref schemeSymbolId, text);
                }
                SymbolScheme scheme = new SymbolScheme(symbolById, symbolIdsByCableId, cableInfoById, text, assignment);
                schemes.Add(scheme);
            }
            return(schemes);
            //layout = new Scheme(deviceGroupById, deviceGroupIdsByCableId, cableInfoById, text);
        }