private string getNumberByActualNumberBase(VeryLongNumberByNumberBaseInString value)
 {
     if (value != null)
     {
         if (NumberBase == NumberBase.Binary)
         {
             return value.getNumberInBase(2);
         }
         if (NumberBase == NumberBase.Decimal)
         {
             return value.getNumberInBase(10);
         }
         if (NumberBase == NumberBase.Hexadecimal)
         {
             return value.getNumberInBase(16);
         }
     }
     return null;
 }
        public bool NextStep()
        {
            switch (state)
            {
                case State.Ready:

                    if (ActionSequence != null && ActionSequence.Count != 0)
                    {
                        string fullName = ActionSequence.ElementAt(0).GetType().Name;
                        int page;

                        switch (fullName)
                        {

                            case "ResolveVirtualAddress":

                                VirtualAddress = new VeryLongNumberByNumberBaseInString(((ResolveVirtualAddress)ActionSequence.ElementAt(0)).Address.ToString(), 10);
                                state = State.Processsing1;

                                break;


                            case "AddPageToMemory":

                                AddPageToMemory pageToAdd = (AddPageToMemory)ActionSequence.ElementAt(0);

                                if (pageToAdd.ProcessPage >= 0 && pageToAdd.ProcessPage < Addressing.NumberOfPages)
                                {
                                    bool isOccupied = false;
                                    foreach (MappingRecordOfProcessAndMemory mapping in ProcessPageAndMemoryPageMapping)
                                    {
                                        if (mapping.MemoryFrame == pageToAdd.MemoryFrame
                                            || mapping.ProcessPage == pageToAdd.ProcessPage)
                                        {
                                            isOccupied = true;
                                            break;
                                        }
                                    }
                                    if (!isOccupied)
                                    {
                                        ProcessPageAndMemoryPageMapping.Add(new MappingRecordOfProcessAndMemory(pageToAdd.ProcessPage, pageToAdd.MemoryFrame));
                                    }
                                }
                                break;


                            case "RemovePageFromMemory":

                                RemovePageFromMemory pageToRemove = (RemovePageFromMemory)ActionSequence.ElementAt(0);

                                MappingRecordOfProcessAndMemory itemToRemove = null;
                                foreach (MappingRecordOfProcessAndMemory mapping in ProcessPageAndMemoryPageMapping)
                                {
                                    if (mapping.MemoryFrame == pageToRemove.MemoryFrame)
                                    {
                                        itemToRemove = mapping;
                                    }
                                }
                                if (itemToRemove != null)
                                {
                                    ProcessPageAndMemoryPageMapping.Remove(itemToRemove);
                                }
                                // törölni kell majd az asszociatív memóriából is
                                ObservableCollection<FourElementTuple> listToRemove = new ObservableCollection<FourElementTuple>();
                                foreach (FourElementTuple record in AssociativeMemory)
                                {
                                    if (record.MappingRecordOfProcessAndMemory.MemoryFrame == pageToRemove.MemoryFrame)
                                    {
                                        listToRemove.Add(record);
                                    }
                                }
                                if (listToRemove != null)
                                {
                                    foreach (FourElementTuple rec in listToRemove)
                                    {
                                        AssociativeMemory.Remove(rec);
                                    }
                                }
                                break;


                            case "AddPageToAssociativeMemory":

                                page = ((AddPageToAssociativeMemory)ActionSequence.ElementAt(0)).ProcessPage;
                                AddPageToAssociativeMemory(page);
  
                                break;


                            case "RemovePageFromAssociativeMemory":

                                page = ((RemovePageFromAssociativeMemory)ActionSequence.ElementAt(0)).ProcessPage;
                                RemovePageToAssociativeMemory(page);

                                break;

                        }
                        ActionSequence.RemoveAt(0);
                    }
                    break;

                case State.Processsing1:

                    string virtAddressBin = VirtualAddress.getNumberInBase(2);

                    if (virtAddressBin.Count() <= Addressing.AddressingBits)
                    {

                        virtAddressBin = completeAddress(Addressing.AddressingBits, virtAddressBin);

                        PageAddress = new VeryLongNumberByNumberBaseInString(virtAddressBin.Substring(0, Addressing.BitsToAddressPages), 2);
                        DistanceOnPage = new VeryLongNumberByNumberBaseInString(virtAddressBin.Substring(Addressing.BitsToAddressPages, Addressing.BitsToAddressOnPage), 2);
                    }
                    else
                    {
                        AddressSourcePageTable = "Segm. Err.";
                        state = State.Finished;
                        break;
                    }

                    state = State.Processsing2;

                    break;


                case State.Processsing2:

                    state = State.Processsing3;
                    AddressSourceAssociative = "No";

                    if (Addressing.IsAssociativeMemoryInUse)
                    {
                        foreach (FourElementTuple record in AssociativeMemory)
                        {
                            if (LargeStringNumberComparator.areEqual(record.MappingRecordOfProcessAndMemory.ProcessPage.ToString(), PageAddress.getNumberInBase(10)))
                            {
                                AddressSourceAssociative = "Yes";
                                FrameAddress = new VeryLongNumberByNumberBaseInString(record.FrameAddress.ToString(), 10);
                                Metrics.makeAssociativeMemoryHit();
                                break;
                            }
                        }
                    }
                    if (AddressSourceAssociative.Equals("Yes"))
                        break;
                    
                    bool isVirtAddressOutOfRange = LargeStringNumberComparator.isFirstGreater(VirtualAddress.getNumberInBase(10), Addressing.ProcessAddressRangeByLastAddress.Address.ToString());
                    bool isVirtAddressUnderZero  = LargeStringNumberComparator.isFirstGreater("0", VirtualAddress.getNumberInBase(10));

                    if (isVirtAddressOutOfRange || isVirtAddressUnderZero)
                    {
                        state = State.Finished;
                        AddressSourcePageTable = "Segm. Err.";
                        break;
                    }


                    AddressSourcePageTable = "PageFault";
                    foreach (MappingRecordOfProcessAndMemory record in ProcessPageAndMemoryPageMapping)
                    {

                        int processPage = Addressing.getProcessPageByVirtualAddress(VirtualAddress.getNumberInBase(10));

                        if (record.ProcessPage.Equals(processPage))
                        {
                            AddressSourcePageTable = "Yes";                            
                            FrameAddress = new VeryLongNumberByNumberBaseInString(Addressing.generateFrameAddress(record).ToString(), 10);

                            Metrics.makePageTableAndAddressHit();
                            break;
                        }
                    }
                    if (AddressSourcePageTable.Equals("PageFault"))
                    {
                        state = State.Finished;
                    }


                    break;

                case State.Processsing3:

                    PhysicalAddress =  new VeryLongNumberByNumberBaseInString(LargeStringNumberComparator.getSum(FrameAddress.getNumberInBase(10), DistanceOnPage.getNumberInBase(10)), 10);

                    state = State.Processsing4;

                    break;

                case State.Processsing4:
                    
                    VirtualAddress = PageAddress = DistanceOnPage = FrameAddress = PhysicalAddress = null;
                    AddressSourceAssociative = AddressSourcePageTable = "";
                    state = State.Ready;

                    break;

                case State.Finished:
                    break;


            }

            OnPropertyChanged("ProcessPageList");
            OnPropertyChanged("MemoryFrameList");

            if (itemsLeft == ActionSequence.Count)
            {
                itemsLeftPeriodCounter++;
            }
            else
            {
                itemsLeftPeriodCounter = 0;
            }
            itemsLeft = ActionSequence.Count;

            if (itemsLeftPeriodCounter > 4)
            {
                return false;
            }
            else
            {
                stepCounter++;
                return true;
            }

        }