public StationLineEntity this[int stationLineId]
        {
            get
            {
                if (stationLineList == null)
                {
                    stationLineList = new List <StationLineEntity>();
                }

                StationLineEntity matchedStationLine = SearchStationLineFromStationLineListByStationLineId(stationLineId);

                if (needCheckQuery)
                {
                    if (matchedStationLine == null)
                    {
                        try
                        {
                            matchedStationLine = SeachStationLineByStationLineIdQuery(stationLineId);
                            stationLineList.Add(matchedStationLine);
                        }
                        catch (Exception exception)
                        {
                            throw exception;
                        }
                    }
                }

                return(matchedStationLine);
            }
        }
        private List <StationLineEntity> SeachStationLineByLineIdQuery(int lineId)
        {
            List <StationLine> matchedStationLineList =
                metroWeb.MetroWebDatabase.Table <StationLine>().Select(new StationLine {
                LineId = lineId
            });

            if (matchedStationLineList.Count == 0)
            {
                throw new Exception(string.Format("The line id {0} is not found.", lineId));
            }

            List <StationLineEntity> matchedStationLineEntityList = new List <StationLineEntity>();

            foreach (StationLine matchedStationLine in matchedStationLineList)
            {
                if (
                    !stationLineList.Exists(stationLine => stationLine.StationLineId == matchedStationLine.StationLineId))
                {
                    StationLineEntity matchedStationLineEntity = new StationLineEntity(metroWeb, matchedStationLine);
                    matchedStationLineEntityList.Add(matchedStationLineEntity);
                }
            }
            return(matchedStationLineEntityList);
        }
        private TimeSpan CalculateTimeCost(StationLineEntityExtender from, StationLineEntityExtender to, List <StationLineEntityExtender> stationLineListCache)
        {
            // Get 'to' previous station lines, and find the station which is the same as the 'from'
            List <StationLineEntityExtender> toPreviousStationLineList = new List <StationLineEntityExtender>();

            toPreviousStationLineList.Add(to);
            toPreviousStationLineList.AddRange(to.PreviousStationLineList.Select(sl => Convert(sl, stationLineListCache)).ToList());

            Stack <StationLineEntityExtender> fromFromToToStationLineStack = new Stack <StationLineEntityExtender>();

            foreach (StationLineEntityExtender toPreviousStationLine in toPreviousStationLineList)
            {
                if (toPreviousStationLine.Station != from.Station)
                {
                    fromFromToToStationLineStack.Push(toPreviousStationLine);
                }
                else
                {
                    fromFromToToStationLineStack.Push(toPreviousStationLine);
                    break;
                }
            }

            if (from.Station != fromFromToToStationLineStack.Peek().Station)
            {
                throw new Exception("From 'from' to 'to' is not in the same line");
            }

            // Calculate the time from 'from' to 'to'
            StationLineEntityExtender transferedLine = fromFromToToStationLineStack.Peek();
            bool     isTransfered     = (from != transferedLine);
            TimeSpan transferTimeCost = new TimeSpan();

            if (isTransfered)
            {
                List <MetroTransferEntity> toMetroTransferList = from.TransferToList;
                MetroTransferEntity        metroTransfer       = toMetroTransferList.Find(mt => Convert(mt.ToStationLine, stationLineListCache) == transferedLine);
                if (metroTransfer == null)
                {
                    throw new Exception("Cannot find the transfer data");
                }
                transferTimeCost = metroTransfer.TimeTransfer + new TimeSpan(transferedLine.TimeWait.Ticks / 2);
            }

            TimeSpan arrivedTimeCost = new TimeSpan();

            fromFromToToStationLineStack.Pop(); // no need to check the first line, if it is transfered, we have already calculated. if not, the arrive time is zero.
            while (fromFromToToStationLineStack.Count > 0)
            {
                StationLineEntity stationline = fromFromToToStationLineStack.Pop();
                arrivedTimeCost += stationline.TimeArrived;
            }

            return(transferTimeCost + arrivedTimeCost);
        }
        internal static StationLineEntityExtender Convert(StationLineEntity stationLine, List <StationLineEntityExtender> stationLineListCache)
        {
            StationLineEntityExtender stationLineExtender = stationLineListCache.Find(cache => cache.StationLineId == stationLine.StationLineId);

            if (stationLineExtender != null)
            {
                return(stationLineExtender);
            }
            else
            {
                stationLineExtender = new StationLineEntityExtender(stationLine);
                stationLineListCache.Add(stationLineExtender);
                return(stationLineExtender);
            }
        }
        private StationLineEntity SeachStationLineByStationLineIdQuery(int stationLineId)
        {
            List <StationLine> matchedStationLineList =
                metroWeb.MetroWebDatabase.Table <StationLine>().Select(new StationLine {
                StationLineId = stationLineId
            });

            if (matchedStationLineList.Count == 0)
            {
                throw new Exception(string.Format("The station line id {0} is not found.", stationLineId));
            }

            StationLineEntity matchedStationLineEntityEntity = new StationLineEntity(metroWeb, matchedStationLineList[0]);

            return(matchedStationLineEntityEntity);
        }
        private List <StationLineEntity> SeachStationLineByQuery()
        {
            List <StationLine> matchedStationLineList =
                metroWeb.MetroWebDatabase.Table <StationLine>().Select();

            List <StationLineEntity> matchedStationLineEntityList = new List <StationLineEntity>();

            foreach (StationLine matchedStationLine in matchedStationLineList)
            {
                if (!stationLineList.Exists(stationLine => stationLine.StationLineId == matchedStationLine.StationLineId))
                {
                    StationLineEntity stationLineEntity = new StationLineEntity(metroWeb, matchedStationLine);
                    matchedStationLineEntityList.Add(stationLineEntity);
                }
            }
            return(matchedStationLineEntityList);
        }
        private bool GenerateRouteTree(StationEntity fromStation, List <StationLineEntityExtender> stationLineListCache, List <Tuple <StationLineEntityExtender, int> > routeTree)
        {
            int index = 0;

            while (index < routeTree.Count)
            {
                StationLineEntityExtender currentStationLineExtender = routeTree[index].Item1;
                List <StationLineEntity>  currentStationLinePreviousStationLineList = currentStationLineExtender.PreviousStationLineList;

                StationLineEntity fromStationLine = currentStationLinePreviousStationLineList.Find(
                    currentStationLinePreviousStationLine => currentStationLinePreviousStationLine.Station == fromStation);

                if (fromStationLine != null)
                {
                    // found
                    StationLineEntityExtender fromStationLineExtender = Convert(fromStationLine, stationLineListCache);
                    routeTree.Add(new Tuple <StationLineEntityExtender, int>(fromStationLineExtender, index));
                    return(true);
                }
                else
                {
                    // not found
                    foreach (StationLineEntity currentStationLinePreviousStationLine in currentStationLinePreviousStationLineList)
                    {
                        if (currentStationLinePreviousStationLine.Station.StationId == 101)
                        {
                        }

                        List <MetroTransferEntity> transferFromList = currentStationLinePreviousStationLine.TransferFromList;
                        foreach (MetroTransferEntity transferFrom in transferFromList)
                        {
                            StationLineEntity         transferFromStationLine         = transferFrom.FromStationLine;
                            StationLineEntityExtender transferFromStationLineExtender = Convert(transferFromStationLine, stationLineListCache);
                            if (!routeTree.Exists(stationLine => stationLine.Item1 == transferFromStationLineExtender))
                            {
                                routeTree.Add(new Tuple <StationLineEntityExtender, int>(transferFromStationLineExtender, index));
                            }
                        }
                    }
                }

                index++;
            }
            return(false);
        }
 internal StationLineEntityExtender(StationLineEntity stationLine)
     : base(stationLine.MetroWeb, stationLine.StationLine)
 {
     Initialize();
 }