/// <summary>
        /// Добавляет команду
        /// </summary>
        public void AddCommand(TariffMetroCommand command)
        {
            if (commands.Any(c => c.ID == command.ID))
            {
                throw new ArgumentException(String.Format("Команда с ID = {0} уже есть в тарифе", command.ID), "command");
            }

            commands.Add(command);
        }
Example #2
0
        public static TariffMetroCommandCalculateInterval First(this TariffMetro tariff)
        {
            TariffMetroCommand cmd = tariff.Commands.FirstOrDefault();

            if (cmd == null)
            {
                return(null);
            }

            while (cmd.Type == TariffMetroCommandType.Goto)
            {
                cmd = tariff.Goto(cmd);
            }

            return((TariffMetroCommandCalculateInterval)cmd);
        }
        /// <summary>
        /// Возвращает копию команды
        /// </summary>
        public override object Clone()
        {
            TariffMetroCommand command = null;

            switch (type)
            {
            case TariffMetroCommandType.CalculateInterval:
                command = new TariffMetroCommandCalculateInterval((TariffMetroCommandCalculateInterval)this);
                break;

            case TariffMetroCommandType.Goto:
                command = new TariffMetroCommandGoto((TariffMetroCommandGoto)this);
                break;
            }

            return(command);
        }
 protected TariffMetroCommand(TariffMetroCommand command)
     : base(command.ID)
 {
     type = command.Type;
 }
        /// <summary>
        /// Создаёт тариф метро из указанного файла
        /// </summary>
        public static Tariff LoadFromFile(string fileName)
        {
            //check file exists
            if (!File.Exists(fileName))
            {
                throw new FileNotFoundException("Файл не найден", fileName);
            }

            //read valid entries
            IEnumerable <string> entries = File.ReadAllLines(fileName, Encoding.Default)
                                           .Where(s => ((s.Length > 3) && (s[0] == CommandStartSign)));

            //create commands and properties
            Dictionary <int, TariffMetroCommand> commands = new Dictionary <int, TariffMetroCommand>();
            Dictionary <char, int> properties             = PropertyNames.ToDictionary(p => p, p => (int)PropertyDefaultValue);

            //parse entries
            foreach (string e in entries)
            {
                //split entry
                string[] sa = SplitEntry(e);

                //get entry name
                char name = sa[0].ToUpper()[1];

                //entry is command?
                if (Char.IsDigit(name))
                {
                    var n = (int)Char.GetNumericValue(name);
                    TariffMetroCommand cmd = ParseCommand(sa);

                    //stop parsing at end command
                    if (cmd.Type == TariffMetroCommandType.End)
                    {
                        break;
                    }

                    cmd.ID = n;
                    commands.Add(n, cmd);
                    continue;
                }

                //entry is property?
                if (!properties.ContainsKey(name))
                {
                    continue;
                }
                properties[name] = ParseProperty(name, sa);
            }

            //check command sequence
            int[] ids = commands.Keys.OrderBy(k => k).ToArray();
            if (commands.Count > 1)
            {
                int firstId = ids[0];
                for (int i = 1; i < ids.Length; i++)
                {
                    if ((ids[i] - ids[i - 1]) > 1)
                    {
                        throw new InvalidDataException("Неверная последовательность команд");
                    }
                }
            }

            //check goto command destinations
            if (commands.Values
                .Where(c => c.Type == TariffMetroCommandType.Goto)
                .Cast <TariffMetroCommandGoto>()
                .Any(g => !ids.Contains(g.Destination)))
            {
                throw new InvalidDataException("Не найдено назначение команды перехода");
            }

            //check cyclic goto (1 level)
            if (commands.Values
                .Where(c => c.Type == TariffMetroCommandType.Goto)
                .Cast <TariffMetroCommandGoto>()
                .Any(g =>
            {
                TariffMetroCommand g2 = commands[g.Destination];
                if (g2.Type != TariffMetroCommandType.Goto)
                {
                    return(false);
                }

                return(((TariffMetroCommandGoto)g2).Destination == g.ID);
            }))
            {
                throw new InvalidDataException("Обнаружен циклический переход");
            }

            //check properties
            if (properties.Values.Any(v => v == PropertyDefaultValue))
            {
                throw new InvalidDataException("Не найдены все свойства");
            }

            //create tariff
            var tariff = new TariffMetro();
            int id     = properties['C'];

            id       += (properties['B'] << 8);
            id       += (properties['A'] << 16);
            tariff.ID = id;

            tariff.PaymentDiscrete      = ConvertMoney(properties['D']);
            tariff.FreeTimeAtStart      = TimeSpan.FromSeconds(properties['E']);
            tariff.FreeTimeAfterPayment = TimeSpan.FromSeconds(properties['F']);

            for (int i = 0; i < ids.Length; i++)
            {
                tariff.AddCommand(commands[i]);
            }

            return(tariff);
        }
Example #6
0
        private static TariffMetroCommand Goto(this TariffMetro tariff, TariffMetroCommand command)
        {
            var g = command as TariffMetroCommandGoto;

            return(g == null ? command : tariff.Commands.FirstOrDefault(c => c.ID == g.Destination));
        }