public void Unpack(FieldList source)
        {
            if (source == null)
            {
                return;
            }

            UnpackDefinitionID(source);

            if (source.GetItemCount(DefAgentFieldID.PaletteEntryIndex) > 0)
            {
                int paletteSize = source[DefAgentFieldID.PaletteSize].AsShort() ?? 0;

                if (paletteSize > 0)
                {
                    // create internal array
                    entries = new PaletteEntryBase[paletteSize];

                    // add entries
                    IEnumerator <IFieldBase> enumerator = source.GetEnumerator();

                    while (enumerator.MoveNext())
                    {
                        if (enumerator.Current.FieldID == (short)DefAgentFieldID.PaletteEntryIndex)
                        {
                            int entryIndex = enumerator.Current.AsShort() ?? -1;

                            if (entryIndex != -1)
                            {
                                enumerator.MoveNext();

                                if (enumerator.Current.FieldID == (short)DefAgentFieldID.PaletteEntryType)
                                {
                                    PaletteEntryType entryType = (PaletteEntryType)(enumerator.Current.AsByte() ?? 0);
                                    PaletteEntryBase newEntry  = null;

                                    switch (entryType)
                                    {
                                    case PaletteEntryType.Undefined:
                                    default:
                                        break;

                                    case PaletteEntryType.Inherited:
                                        newEntry = new InheritedPaletteEntry();
                                        break;

                                    case PaletteEntryType.DoNotPaint:
                                        newEntry = new DoNotPaintPaletteEntry();
                                        break;

                                    case PaletteEntryType.FontReference:
                                    {
                                        enumerator.MoveNext();

                                        if (enumerator.Current.FieldID == (short)DefAgentFieldID.PaletteEntryData)
                                        {
                                            int fontDefID = enumerator.Current.AsInteger() ?? -1;

                                            if (fontDefID != -1)
                                            {
                                                newEntry = new FontReferencePaletteEntry(fontDefID);
                                            }
                                        }

                                        break;
                                    }

                                    case PaletteEntryType.Image:
                                    {
                                        break;
                                    }

                                    case PaletteEntryType.Colour:
                                    {
                                        enumerator.MoveNext();

                                        if (enumerator.Current.FieldID == (short)DefAgentFieldID.PaletteEntryData)
                                        {
                                            int?argb = enumerator.Current.AsInteger();

                                            if (argb.HasValue)
                                            {
                                                newEntry = new ColourPaletteEntry(argb.Value);
                                            }
                                        }

                                        break;
                                    }

                                    case PaletteEntryType.LinearGradient:
                                    {
                                        enumerator.MoveNext();

                                        if (enumerator.Current.FieldID == (short)DefAgentFieldID.PaletteEntryData)
                                        {
                                            FieldList gradientData = enumerator.Current as FieldList;

                                            if (gradientData != null)
                                            {
                                                newEntry = new LinearGradientPaletteEntry(gradientData);
                                            }
                                        }

                                        break;
                                    }

                                    case PaletteEntryType.ColourSequence:
                                    {
                                        enumerator.MoveNext();

                                        if (enumerator.Current.FieldID == (short)DefAgentFieldID.PaletteEntryData)
                                        {
                                            FieldList clsData = enumerator.Current as FieldList;

                                            if (clsData != null)
                                            {
                                                newEntry = new ColourSequencePaletteEntry(clsData);
                                            }
                                        }

                                        break;
                                    }

                                    case PaletteEntryType.PaletteReference:
                                    {
                                        enumerator.MoveNext();

                                        if (enumerator.Current.FieldID == (short)DefAgentFieldID.PaletteEntryData)
                                        {
                                            int rf = enumerator.Current.AsInteger() ?? -1;

                                            if (rf != -1)
                                            {
                                                newEntry = new PaletteReferencePaletteEntry(rf);
                                            }
                                        }

                                        break;
                                    }

                                    case PaletteEntryType.StyleSet:
                                    case PaletteEntryType.SystemDialogRoot:
                                    case PaletteEntryType.SystemDialogContainer:
                                    case PaletteEntryType.SystemDialogTitle:
                                    case PaletteEntryType.SystemDialogStaticText:
                                    case PaletteEntryType.SystemDialogListEntry:
                                    case PaletteEntryType.SystemDialogMenuBar:
                                    {
                                        enumerator.MoveNext();

                                        if (enumerator.Current.FieldID == (short)DefAgentFieldID.PaletteEntryData)
                                        {
                                            FieldList styleSetData = enumerator.Current as FieldList;

                                            if (styleSetData != null)
                                            {
                                                StyleSet sst = new StyleSet(entryType);
                                                sst.Unpack(styleSetData);

                                                newEntry = sst;
                                            }
                                        }

                                        break;
                                    }
                                    }

                                    if (newEntry != null)
                                    {
                                        entries[entryIndex] = newEntry;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // done
            IsUnpacked = true;
        }
        public void Unpack(FieldList source)
        {
            if (source == null)
            {
                return;
            }

            UnpackDefinitionID(source);

            Background = new PaintStyle(source, DefAgentFieldID.BackgroundPaintStyle);

            UIFlowDirection fd = (UIFlowDirection)(source[DefAgentFieldID.FlowDirection].AsByte() ?? (byte)UIFlowDirection.Down);

            IsHorizontal = (fd == UIFlowDirection.Right);

            BackgroundImageCrop   = (CropStrategy)(source[DefAgentFieldID.BackgroundCropStrategy].AsNumber() ?? 0);
            SizeToBackgroundImage = source[DefAgentFieldID.BlockSizeToBackground].AsBoolean() ?? false;
            ScrollableBackground  = source[DefAgentFieldID.BackgroundScrollable].AsBoolean() ?? false;

            NumberOfFullyVisibleChildrenInHorizontalMode = source[DefAgentFieldID.VisibleChildren].AsShort() ?? 4;

            AllowAutoScroll       = source.GetItemCount(DefAgentFieldID.AllowAutoscroll) > 0;
            EnforceRadioBehaviour = source.GetItemCount(DefAgentFieldID.EnforceRadio) > 0;

            ScrollIndicationType = (ScrollIndication)(source[DefAgentFieldID.ScrollIndicationType].AsByte() ?? (byte)ScrollIndication.Bar);

            Spacing = source[DefAgentFieldID.Spacing].AsShort() ?? 0;

            UnpackMarginsAndPadding(source);

            BlockFocusBehaviour = (FocusBehaviour)(source[DefAgentFieldID.FocusBehaviour].AsByte() ?? (byte)FocusBehaviour.Normal);
            BlockFocusPosition  = (FocusPosition)(source[DefAgentFieldID.FocusPosition].AsByte() ?? (byte)FocusPosition.Free);

            MaximumNumberOfChildren = source[DefAgentFieldID.MaximumChildren].AsShort() ?? DefaultMaximumNumberOfChildren;

            InsertFromTheTop = !(source[DefAgentFieldID.FromBottom].AsBoolean() ?? false);

            BlockTickerSpeed = (TickerSpeed)(source[DefAgentFieldID.TickerSpeed].AsByte() ?? (byte)TickerSpeed.Medium);

            switch (BlockTickerSpeed)
            {
            case TickerSpeed.Slow:
                TicksPerUnit  = 1;
                PixelsPerUnit = 1;
                break;

            case TickerSpeed.Medium:
            default:
                TicksPerUnit  = 0;
                PixelsPerUnit = 1;
                break;

            case TickerSpeed.Fast:
                TicksPerUnit  = 0;
                PixelsPerUnit = 2;
                break;
            }

            TickerDirection = (TickerFlowDirection)(source[DefAgentFieldID.TickerDirection].AsByte() ?? (byte)TickerFlowDirection.Forwards);

            TickerItemPause tickerPauseSetting = (TickerItemPause)(source[DefAgentFieldID.PauseBetweenItem].AsByte() ?? (byte)TickerItemPause.None);

            switch (tickerPauseSetting)
            {
            case TickerItemPause.Long:
                TickerPauseTimeOnItem = 300;
                break;

            case TickerItemPause.Medium:
                TickerPauseTimeOnItem = 150;
                break;

            case TickerItemPause.Short:
                TickerPauseTimeOnItem = 50;
                break;

            case TickerItemPause.None:
            default:
                TickerPauseTimeOnItem = 0;
                break;
            }

            Paginate = source[DefAgentFieldID.UsePagination].AsBoolean() ?? false;

            // get list of striping palette references
            FieldList stripes = source[DefAgentFieldID.StripeStyles] as FieldList;

            if (stripes != null)
            {
                List <Int16Field> stripesData = source.GetItems <Int16Field>(DefAgentFieldID.PaletteEntryIndex);

                foreach (Int16Field field in stripesData)
                {
                    Stripes.Add(field.Data);
                }
            }

            IsFloating = source[DefAgentFieldID.FloatBehaviour].AsBoolean() ?? false;

            UnpackBlockHints(source);

            // done
            IsUnpacked = true;
        }
        public void Unpack(FieldList source)
        {
            if (source == null)
            {
                return;
            }

            UnpackDefinitionID(source);

            IsCheckable       = false;
            DeviceTextScaling = false;

            // unpacking common attributes
            SpecialTag            = source[DefAgentFieldID.DefinitionSpecialTag].AsInteger() ?? -1;
            BackgroundImageCrop   = (CropStrategy)(source[DefAgentFieldID.BackgroundCropStrategy].AsNumber() ?? 0);
            SizeToBackgroundImage = source[DefAgentFieldID.BlockSizeToBackground].AsBoolean() ?? false;
            AcceptsFocus          = source[DefAgentFieldID.AcceptsFocus].AsBoolean() ?? false;
            SortIndex             = source[DefAgentFieldID.SortSlotIndex].AsShort() ?? -1;

            // static display data
            int numberOfDisplayData = source.GetItemCount(MessageOutFieldID.SlotDisplayDataTypeID);

            if (numberOfDisplayData > 0)
            {
                StaticDisplayData = DisplayData.Parse(source);
            }

            // loop through states
            PairedList <ByteField, FieldList> states =
                source.GetPairedItems <ByteField, FieldList>(DefAgentFieldID.ComponentState, DefAgentFieldID.DataPerComponentState);

            foreach (Pair <ByteField, FieldList> item in states)
            {
                BlockState state   = (BlockState)item.First.Data;
                FieldList  newData = item.Second;

                AtomicBlockStateData data = GetOrCreateDataForState(state);

                // mark as checkable if applicable
                if ((state == BlockState.CheckedNormal) || (state == BlockState.CheckedFocused))
                {
                    IsCheckable = true;
                }

                // set paint styles
                data.ComponentForeground = new PaintStyle(newData, DefAgentFieldID.ForegroundPaintStyle);
                data.ComponentBackground = new PaintStyle(newData, DefAgentFieldID.BackgroundPaintStyle);

                // font reference
                data.ComponentFont = newData[DefAgentFieldID.FontReference].AsShort() ?? 0;

                // margins and paddings
                data.MarginLeft    = newData[DefAgentFieldID.LeftMargin2].AsShort() ?? 0;
                data.MarginTop     = newData[DefAgentFieldID.TopMargin2].AsShort() ?? 0;
                data.MarginRight   = newData[DefAgentFieldID.RightMargin].AsShort() ?? 0;
                data.MarginBottom  = newData[DefAgentFieldID.BottomMargin].AsShort() ?? 0;
                data.PaddingLeft   = newData[DefAgentFieldID.LeftPadding2].AsShort() ?? 0;
                data.PaddingTop    = newData[DefAgentFieldID.TopPadding2].AsShort() ?? 0;
                data.PaddingRight  = newData[DefAgentFieldID.RightPadding].AsShort() ?? 0;
                data.PaddingBottom = newData[DefAgentFieldID.BottomPadding].AsShort() ?? 0;

                // slot data
                List <FieldList> slotsData = newData.GetItems <FieldList>(DefAgentFieldID.SlotData);

                foreach (FieldList sd in slotsData)
                {
                    SlotData info = new SlotData();

                    info.Foreground = new PaintStyle(sd, DefAgentFieldID.ForegroundPaintStyle);
                    info.Background = new PaintStyle(sd, DefAgentFieldID.BackgroundPaintStyle);
                    info.Font       = sd[DefAgentFieldID.FontReference].AsShort() ?? 0;
                    info.SlotIndex  = sd[DefAgentFieldID.SlotIndex].AsShort() ?? 0;

                    // rendering hints
                    if ((SlotHints == null) || (SlotHints.Length <= info.SlotIndex) || (SlotHints[(int)info.SlotIndex] == null))
                    {
                        string newSlotHint = sd[DefAgentFieldID.SlotHint].AsString();

                        if (newSlotHint != null)
                        {
                            if (SlotHints == null)
                            {
                                SlotHints = new string[Math.Max(slotsData.Count, (int)(info.SlotIndex + 1))];
                            }
                            else if (SlotHints.Length <= info.SlotIndex)
                            {
                                Array.Resize <string>(ref SlotHints, Math.Max(slotsData.Count, (int)(info.SlotIndex + 1)));
                            }

                            SlotHints[(int)info.SlotIndex] = newSlotHint;
                        }
                    }

                    data.SlotInfo.Add(info);
                }

                // unpack layout
                LayoutType layoutType = (LayoutType)(newData[DefAgentFieldID.LayoutType].AsByte() ?? 0);

                if (layoutType == LayoutType.Table)
                {
                    // currently only table layout is supported for atomic blocks
                    data.LayoutTemplate = new TableLayoutTemplate(newData);
                }

                stateData.Add(state, data);
            }

            // rendering hints for the block
            UnpackBlockHints(source);

            // done
            IsUnpacked = true;
        }