/**
  * Retrieves the currently focused item that has specified the attribute
  *
  * @param attribute the attribute
  * @param container the container that should have focused the item
  * @return the item that contains the attribute or the focused item which is not a Container
  *     itself
  */
 protected Item getFocusedItemWithAttribute(String attribute, Container container) {
   Item item = container.getFocusedItem();
   if (item != null && item.getAttribute(attribute) == null && item instanceof Container) {
     return getFocusedItemWithAttribute(attribute, (Container) item);
   }
   return item;
 }
  protected void handleSubmitCommand() {
    Item submitItem = this.browser.getFocusedItem();
    HtmlForm form = (HtmlForm) submitItem.getAttribute(ATTR_FORM);
    while (form == null && (submitItem instanceof Container)) {
      submitItem = ((Container) submitItem).getFocusedItem();
      form = (HtmlForm) submitItem.getAttribute(ATTR_FORM);
    }
    if (form == null) {
      return;
    }

    form.submit(submitItem);
  }
Example #3
0
  Item createItem() {
    Item item = this.handler.createContent(this);

    if (item != null) {
      item.setView(new ContentView(item));
      if (isInteractive()) {
        // #debug sl.debug.event
        System.out.println("element " + this + " is interactive");
        item.setAppearanceMode(Item.INTERACTIVE);
      }
    }

    return item;
  }
  protected void handleLinkCommand() {

    Item linkItem = getFocusedItemWithAttribute(ATTR_HREF, this.browser);
    if (linkItem == null) {
      return;
    }
    String href = (String) linkItem.getAttribute(ATTR_HREF);
    if (href != null) {
      this.browser.go(this.browser.makeAbsoluteURL(href));
    }
    // #if polish.debug.error
    else {
      // #debug error
      System.out.println(
          "Unable to handle link command for item "
              + linkItem
              + ": no "
              + ATTR_HREF
              + " attribute found.");
    }
    // #endif
  }
Example #5
0
  /* (non-Javadoc)
   * @see de.enough.polish.ui.Item#handlePointerReleased(int, int)
   */
  protected boolean handlePointerReleased(int relX, int relY) {
    if (this.isInItemArea(relX, relY)) {
      super.handlePointerReleased(relX, relY);

      boolean multipleClick = isMultipleClick();

      if (multipleClick) {
        this.currentIndex = (this.currentIndex + 1) % this.keys.length();
      } else {
        this.currentIndex = 0;
      }

      apply(multipleClick);

      this.keyboard.lastKey = this;

      return true;
    } else {
      return false;
    }
  }
  /* (non-Javadoc)
   * @see de.enough.polish.ui.ContainerView#paintItem(de.enough.polish.ui.Item, int, int, int, int, int, int, int, int, int, javax.microedition.lcdui.Graphics)
   */
  protected void paintItem(
      Item item,
      int index,
      int x,
      int y,
      int leftBorder,
      int rightBorder,
      int clipX,
      int clipY,
      int clipWidth,
      int clipHeight,
      Graphics g) {
    // #if polish.midp2
    int width = this.shownRgbDataWidths[index];
    int height = this.shownRgbDataHeights[index];
    if (index == this.focusedIndex
        && (width == this.originalRgbDataWidths[index])
        && (this.currentTranslucencies[index] == this.targetTranslucencies[index])) {
      super.paintItem(
          item, index, x, y, leftBorder, rightBorder, clipX, clipY, clipWidth, clipHeight, g);
      return;
    }
    int[] data = this.shownRgbData[index];

    int itemLayout = item.getLayout();
    if ((itemLayout & Item.LAYOUT_VCENTER) == Item.LAYOUT_VCENTER) {
      y += (this.maxItemHeight - height) >> 1;
    } else if ((itemLayout & Item.LAYOUT_BOTTOM) == Item.LAYOUT_BOTTOM) {
      y += (this.maxItemHeight - height);
    }
    DrawUtil.drawRgb(data, x, y, width, height, true, g);
    //			g.setColor( 0xffff00);
    //			g.drawRect( x, y, item.itemWidth, item.itemHeight );
    //			g.drawLine( x, y, x + item.itemWidth, y + item.itemHeight );
    // #else
    // # super.paintItem(item, index, x, y, leftBorder, rightBorder, clipX, clipY, clipWidth,
    // clipHeight, g);
    // #endif
  }
  /* (non-Javadoc)
   * @see de.enough.polish.ui.ContainerView#initContent(de.enough.polish.ui.Container, int, int)
   */
  protected void initContent(Item parentItm, int firstLineWidth, int availWidth, int availHeight) {
    Container parent = (Container) parentItm;
    // #debug
    System.out.println(
        "Initalizing HorizontalContainerView with focusedIndex="
            + parent.getFocusedIndex()
            + " for parent "
            + parent);

    this.availableWidth = availWidth;

    int arrowWidth = 0;
    if (this.arrowLeft != null && this.arrowRight != null) {
      arrowWidth =
          this.arrowLeft.getWidth() + this.arrowRight.getWidth() + (this.paddingHorizontal * 2);
      availWidth -= arrowWidth;
      firstLineWidth -= arrowWidth;
    }

    int selectedItemIndex = parent.getFocusedIndex();
    int maxHeight = 0;
    int completeWidth = 0;
    if (arrowWidth > 0) {
      completeWidth = this.arrowLeft.getWidth() + this.paddingHorizontal;
    }
    Item[] items = parent.getItems();
    // #if polish.css.show-text-in-title
    if (this.isShowTextInTitle && (this.labels == null || this.labels.length != items.length)) {
      this.labels = new String[items.length];
    }
    // #endif

    int availItemWidth = availWidth;
    int availItemWidthWithPaddingShift8 = 0;
    // #if polish.css.horizontalview-distribution
    if (this.isDistributeEquals) {
      int left = availItemWidth - ((items.length - 1) * this.paddingHorizontal);
      availItemWidth = left / items.length;
      availItemWidthWithPaddingShift8 = (availWidth << 8) / items.length;
      // check if we have too many items for the available width:
      if (items.length > 0) {
        Item child = items[0];
        int childWidth = child.getItemWidth(availItemWidth, availItemWidth, availHeight);
        if (child.getContentWidth() > childWidth) {
          childWidth = child.getContentWidth() + child.getPaddingLeft() + child.getPaddingRight();
        }
        // System.out.println("childWidth=" + childWidth + ", available=" + availItemWidth);
        if (childWidth > availItemWidth) {
          availItemWidth = childWidth;
          availItemWidthWithPaddingShift8 = (childWidth + this.paddingHorizontal) << 8;
        }
      }
    }
    // #endif
    for (int i = 0; i < items.length; i++) {
      Item item = items[i];
      // #if polish.css.show-text-in-title
      if (this.isShowTextInTitle) {
        String text = item.getLabel();
        if (text != null) {
          this.labels[i] = text;
          item.setLabel(null);
        } else if (item instanceof IconItem) {
          IconItem iconItem = (IconItem) item;
          text = iconItem.getText();
          if (text != null) {
            this.labels[i] = text;
            iconItem.setTextVisible(false);
          }
        }
      }
      // #endif
      int itemHeight = item.getItemHeight(availItemWidth, availItemWidth, availHeight);
      int itemWidth = item.itemWidth;
      if (itemHeight > maxHeight) {
        maxHeight = itemHeight;
      }
      boolean isLast = (i == items.length - 1);
      if (isLast && item.isLayoutRight() && (completeWidth + item.itemWidth < availWidth)) {
        completeWidth = availWidth - item.itemWidth;
      }
      int startX = completeWidth;
      item.relativeX = completeWidth;
      item.relativeY = 0;
      completeWidth += itemWidth + (isLast ? 0 : this.paddingHorizontal);
      // #if polish.css.horizontalview-distribution
      if (this.isDistributeEquals) {
        completeWidth = (availItemWidthWithPaddingShift8 * (i + 1)) >> 8;
        if (itemWidth < availItemWidth) {
          if (item.isLayoutCenter()) {
            item.relativeX += (availItemWidth - itemWidth) / 2;
          } else if (item.isLayoutRight() && !isLast) {
            item.relativeX += (availItemWidth - itemWidth);
          }
        }
      }
      // #endif
      if (i == selectedItemIndex) {
        if (startX + getScrollXOffset() < 0) {
          setScrollXOffset(-startX, true);
        } else if (completeWidth + getScrollTargetXOffset() > availWidth) {
          setScrollXOffset(availWidth - completeWidth, true);
        }
        // System.out.println("initContent: xOffset=" + xOffset);
        this.focusedItem = item;
      }
      if (item.appearanceMode != Item.PLAIN) {
        this.appearanceMode = Item.INTERACTIVE;
      }
    }
    for (int i = 0; i < items.length; i++) {
      Item item = items[i];
      // #if polish.css.horizontalview-align-heights
      if (this.isAlignHeights && !item.isLayoutVerticalShrink()) {
        item.setItemHeight(maxHeight);
      } else
      // #endif
      if (item.isLayoutVerticalCenter()) {
        item.relativeY += (maxHeight - item.itemHeight) >> 1;
      } else if (item.isLayoutBottom()) {
        item.relativeY += (maxHeight - item.itemHeight);
      }
      if (i == items.length - 1 && item.isLayoutRight() && completeWidth < availWidth) {
        item.relativeX = availWidth - item.itemWidth;
        completeWidth = availWidth;
      }
    }
    this.contentHeight = maxHeight;
    if (arrowWidth > 0) {
      if (parent.isLayoutVerticalCenter()) {
        this.arrowLeftYAdjust = (maxHeight - this.arrowLeft.getHeight()) / 2;
        this.arrowRightYAdjust = (maxHeight - this.arrowRight.getHeight()) / 2;
      } else if (parent.isLayoutBottom()) {
        this.arrowLeftYAdjust = (maxHeight - this.arrowLeft.getHeight());
        this.arrowRightYAdjust = (maxHeight - this.arrowRight.getHeight());
      }
    }
    if (completeWidth > availWidth) {
      this.isClippingRequired = true;
    } else {
      this.isClippingRequired = false;
    }
    if (arrowWidth > 0) {
      completeWidth += this.arrowRight.getWidth() + this.paddingHorizontal;
    }
    this.contentWidth = completeWidth;

    if (parent.isLayoutRight() && parent.isLayoutExpand()) {
      this.isExpandRightLayout = true;
    } else {
      this.isExpandRightLayout = false;
    }
    // System.out.println("init of horizontal: " + this.contentWidth + "x" + this.contentHeight);
  }
  /* (non-Javadoc)
   * @see de.enough.polish.ui.ContainerView#focusItem(int, de.enough.polish.ui.Item, int, de.enough.polish.ui.Style)
   */
  public Style focusItem(int focIndex, Item item, int direction, Style focStyle) {
    // #debug
    System.out.println(
        "Horizontal: focusing " + focIndex + ", clippingRequired=" + this.isClippingRequired);
    // #if polish.css.show-text-in-title
    if (this.isShowTextInTitle) {
      Screen scr = getScreen();
      if (scr != null) {
        scr.setTitle(this.labels[focIndex]);
      }
    }
    // #endif
    if (item != null) {
      if (this.isClippingRequired) {
        int leftStart = 0;
        Image right = this.arrowRight;
        Image left = this.arrowLeft;
        boolean paintArrows = (right != null) && (left != null);
        int availWidth = this.availableWidth;
        if (paintArrows) {
          leftStart = left.getWidth() + this.paddingHorizontal;
          availWidth -= right.getWidth() + this.paddingHorizontal;
        }
        int scrollXOffset = getScrollTargetXOffset();
        int targetScrollXOffset = -1;
        if ((scrollXOffset + item.relativeX < leftStart)
        //					//#ifdef polish.css.scroll-continuous
        //						&& (!this.scrollContinuous || (scrollXOffset + item.relativeX + item.itemWidth +
        // this.contentWidth <= availWidth))
        //					//#endif
        ) {
          targetScrollXOffset = leftStart - item.relativeX;
        } else if ((scrollXOffset + item.relativeX + item.itemWidth > availWidth)
        //					//#ifdef polish.css.scroll-continuous
        //						&& (!this.scrollContinuous || (scrollXOffset + item.relativeX - this.contentWidth >=
        // leftStart))
        //					//#endif
        ) {
          targetScrollXOffset = availWidth - item.relativeX - item.itemWidth;
        }
        //				//#ifdef polish.css.scroll-continuous
        //					if ((targetScrollXOffset != -1) && this.scrollContinuous) {
        //
        //						// check if item is possibly in the visible area already (the virtual copy, to be
        // precise):
        //						if (targetScrollXOffset < scrollXOffset) {
        //							// moving to the left:
        //							if (scrollXOffset + this.contentWidth + item.relativeX > leftStart) {
        //								targetScrollXOffset = -1;
        //							}
        //						} else {
        //							// moving to the right:
        //						}
        //						// also check if we really need to scroll that far, e.g. when moving to the first or
        // last item:
        //
        //						setScrollXOffset( scrollXOffset - this.contentWidth, false);
        //						targetScrollXOffset = -scrollXOffset - item.relativeX;
        //					}
        //				//#endif

        if (targetScrollXOffset != -1) {
          setScrollXOffset(targetScrollXOffset, true);
        }
      }
      // #if polish.css.horizontalview-align-heights
      Item lastFocusedItem = this.focusedItem;
      if (this.isAlignHeights
          && lastFocusedItem != null
          && lastFocusedItem.getContentHeight() < item.getContentHeight()) {
        this.parentContainer.setInitialized(false);
      }
      // #endif
      return super.focusItem(focIndex, item, direction, focStyle);
    }

    return null;
  }
  /* (non-Javadoc)
   * @see de.enough.polish.ui.ContainerView#focusItem(int, de.enough.polish.ui.Item, int, de.enough.polish.ui.Style)
   */
  public Style focusItem(int focIndex, Item item, int direction, Style focStyle) {
    if (this.referenceXCenterPositions == null
        || this.referenceXCenterPositions.length != this.parentContainer.size()) {
      this.focusedStyle = focStyle;
      this.focusedDirection = direction;
      this.focusedIndex = focIndex;
      this.focusedItem = item;
      return item.getStyle();
    } else {
      int difference = this.referenceFocusedIndex - focIndex;
      Item[] myItems = this.parentContainer.getItems();
      int[] targetXPositions;
      int[] targetYPositions = null;
      // #if polish.midp2
      int[] targetAlphas;
      int[] currentAlphas;
      // #endif
      if (this.targetXCenterPositions == null
          || this.targetXCenterPositions.length != myItems.length) {
        targetXPositions = new int[myItems.length];
        if (this.referenceYCenterPositions != null) {
          targetYPositions = new int[myItems.length];
        }
        // #if polish.midp2
        targetAlphas = new int[myItems.length];
        currentAlphas = new int[myItems.length];
        // #endif
      } else {
        targetXPositions = this.targetXCenterPositions;
        if (this.referenceYCenterPositions != null) {
          targetYPositions = this.targetYCenterPositions;
        }
        // #if polish.midp2
        targetAlphas = this.targetTranslucencies;
        currentAlphas = this.currentTranslucencies;
        // #endif
      }
      if (this.referenceXCenterPositions.length != targetXPositions.length) {
        return item.getStyle();
      }
      for (int i = 0; i < myItems.length; i++) {
        int nextIndex = i + difference;
        if (nextIndex < 0) {
          nextIndex = myItems.length + nextIndex;
        } else if (nextIndex >= myItems.length) {
          nextIndex -= myItems.length;
        }
        targetXPositions[i] = this.referenceXCenterPositions[nextIndex];
        if (targetYPositions != null) {
          targetYPositions[i] = this.referenceYCenterPositions[nextIndex];
        }
        // #if polish.midp2
        targetAlphas[i] = calculateAlpha(getDistance(i, focIndex, myItems.length), myItems.length);
        // System.out.println("targetAlpha[" + i + "]=" + targetAlphas[i]);
        currentAlphas[i] = this.endTranslucency;
        // #endif
      }
      this.targetXCenterPositions = targetXPositions;
      if (targetYPositions != null) {
        this.targetYCenterPositions = targetYPositions;
      }
      // #if polish.midp2
      this.targetTranslucencies = targetAlphas;
      this.currentTranslucencies = currentAlphas;
      // #endif
    }
    Style itemStyle;
    if (!item.isFocused) {
      itemStyle = super.focusItem(focIndex, item, direction, focStyle);
    } else {
      itemStyle = item.getStyle();
    }

    this.focusedBackground = removeItemBackground(item);
    this.focusedBorder = removeItemBorder(item);
    if (this.isRemoveText) {
      if (this.isShowTextInTitle) {
        Screen scr = getScreen();
        if (scr != null) {
          scr.setTitle(this.labels[focIndex]);
        }
      } else {
        StringItem focLabel = this.focusedLabel;
        if (focLabel != null) {
          int previousHeight = focLabel.itemHeight;
          focLabel.setText(this.labels[focIndex]);
          if (focLabel.getStyle() != item.getStyle()
          // #if polish.css.fisheyeview-text-style
          // # && (this.focusedLabelStyle == null)
          // #endif
          ) {
            focLabel.setStyle(item.getStyle());
            removeItemBackground(focLabel);
            removeItemBorder(focLabel);
          }
          if (focLabel.getAvailableHeight() != 0) {
            int currentHeight =
                focLabel.getItemHeight(
                    focLabel.getAvailableWidth(),
                    focLabel.getAvailableWidth(),
                    focLabel.getAvailableHeight());
            if (currentHeight != previousHeight) {
              this.contentHeight += (currentHeight - previousHeight);
              this.parentContainer.setInitialized(false);
            }
          }
        }
      }
    }
    return itemStyle;
  }
  /* (non-Javadoc)
   * @see de.enough.polish.ui.ContainerView#initContent(de.enough.polish.ui.Container, int, int)
   */
  protected void initContent(
      Item parentContainerItem, int firstLineWidth, int availWidth, int availHeight) {

    // #if polish.hasPointerEvents
    if (!isPointerDraggedEnabled) {
      isPointerDraggedEnabled = Display.getInstance().hasPointerMotionEvents();
    }
    // #endif
    this.isVertical = false;
    this.isHorizontal = true;
    Container parent = (Container) parentContainerItem;
    // #debug
    // # System.out.println("FishEye: intialising content for " + this + " with vertical-padding " +
    // this.paddingVertical + ", availWidth=" + availWidth );

    this.parentContainer = parent;
    Item[] myItems = parent.getItems();
    int length = myItems.length;
    if (this.focusedIndex == -1 && length != 0) {
      // this.parentContainer.focus(0);
      if (parent.focusedIndex != -1) {
        this.focusedIndex = parent.focusedIndex;
      } else {
        this.focusedIndex = 0;
      }
      // System.out.println("AUTO-FOCUSSING ITEM " + this.focusedIndex );
      this.focusedItem = myItems[this.focusedIndex];
      this.focusedStyle = this.focusedItem.getFocusedStyle();
    }
    if (this.referenceXCenterPositions != null && this.referenceXCenterPositions.length == length) {
      // only another item has been focused, so nothing needs to be adjusted.
      return;
    }

    // #if polish.css.show-text-in-title
    // # if (this.isRemoveText && this.focusedLabel == null && !this.isShowTextInTitle) {
    // # this.focusedLabel = new StringItem(null, null);
    // #if polish.css.fisheyeview-text-style
    // # if (this.focusedLabelStyle != null) {
    // # this.focusedLabel.setStyle(this.focusedLabelStyle);
    // # }
    // #endif
    // # }
    // #else
    if (this.isRemoveText && this.focusedLabel == null) {
      this.focusedLabel = new StringItem(null, null);
      // #if polish.css.fisheyeview-text-style
      // # if (this.focusedLabelStyle != null) {
      // # this.focusedLabel.setStyle(this.focusedLabelStyle);
      // # }
      // #endif
    }
    // #endif

    if (this.isRemoveText && (this.labels == null || this.labels.length != length)) {
      this.labels = new String[length];
    }

    int maxWidth = 0;
    int maxHeight = 0;
    boolean hasFocusableItem = false;
    // #if polish.midp2
    this.originalRgbData = new int[length][];
    this.originalRgbDataWidths = new int[length];
    this.shownRgbData = new int[length][];
    this.shownRgbDataWidths = new int[length];
    this.shownRgbDataHeights = new int[length];
    // #endif
    for (int i = 0; i < length; i++) {
      Item item = myItems[i];
      if (this.isRemoveText) {
        String text = item.getLabel();
        if (text != null) {
          this.labels[i] = text;
          item.setLabel(null);
        } else if (item instanceof IconItem) {
          IconItem iconItem = (IconItem) item;
          text = iconItem.getText();
          if (text != null) {
            this.labels[i] = text;
            iconItem.setTextVisible(false);
            // iconItem.setText(null);
          }
        }
      }
      int width = item.getItemWidth(firstLineWidth, availWidth, availHeight);
      int height = item.getItemHeight(firstLineWidth, availWidth, availHeight);
      // #if polish.midp2
      int[] data = item.getRgbData(true, 255);
      this.originalRgbData[i] = data;
      this.originalRgbDataWidths[i] = width;
      if (this.scaleFactor == 100) {
        this.shownRgbData[i] = data;
        this.shownRgbDataWidths[i] = width;
        this.shownRgbDataHeights[i] = height;
      } else {
        int newWidth = (width * this.scaleFactor) / 100;
        int newHeight = (height * this.scaleFactor) / 100;
        // this.shownRgbData[i] = ImageUtil.scale(data, newWidth, newHeight, width, height );
        int alpha =
            this
                .endTranslucency; // calculateAlpha( getDistance( i, this.focusedIndex, length ),
                                  // length );
        this.shownRgbData[i] = new int[data.length];
        // #if polish.FishEye.scaleHq
        // # ImageUtil.scaleDownHq(this.shownRgbData[i], data,width, newWidth, 0, alpha, false);
        // #else
        ImageUtil.scale(alpha, data, newWidth, newHeight, width, height, this.shownRgbData[i]);
        // #endif

        this.shownRgbDataWidths[i] = newWidth;
        this.shownRgbDataHeights[i] = newHeight;
      }
      // #endif
      if (item.appearanceMode != Item.PLAIN) {
        hasFocusableItem = true;
      }
      if (width > maxWidth) {
        maxWidth = width;
      }
      if (height > maxHeight) {
        maxHeight = height;
      }
    }
    this.maxItemHeight = maxHeight;
    if (hasFocusableItem) {
      this.appearanceMode = Item.INTERACTIVE;
    } else {
      this.appearanceMode = Item.PLAIN;
    }

    initItemArrangement(availWidth, availHeight, myItems, length, maxWidth, maxHeight);

    // use reference positions to set the position for the items:
    for (int i = 0; i < length; i++) {
      Item item = myItems[i];
      int distance = getDistance(i, this.focusedIndex, length);
      if (distance != 0) {
        distance--;
      }
      int halfItemWidth = (item.getItemWidth(availWidth, availWidth, availHeight) >> 1);
      int halfItemHeight = (item.getItemHeight(availWidth, availWidth, availHeight) >> 1);
      // #if polish.midp2
      if (i != this.focusedIndex) {
        int factor = getScaleFactor(distance, length);
        halfItemWidth = (halfItemWidth * factor) / 100;
        halfItemHeight = (halfItemHeight * factor) / 100;
      }
      // #endif
      // System.out.println(i + ": initContent:  with distance " + distance + ", halfItemWidth=" +
      // halfItemWidth + ", focusedIndex=" + this.focusedIndex);
      item.relativeX = this.referenceXCenterPositions[i] - halfItemWidth;
      if (this.referenceYCenterPositions != null) {
        item.relativeY = this.referenceYCenterPositions[i] - halfItemHeight;
      }
      // System.out.println( i + ": relativeX=" + item.relativeX);

      //			System.out.println("item.relativeX for " + i + "=" + item.relativeX);
    }
    if (this.focusedStyle != null) {
      focusItem(this.focusedIndex, this.focusedItem, this.focusedDirection, this.focusedStyle);
      this.focusedItem.relativeX =
          this.referenceXCenterPositions[this.focusedIndex]
              - (this.focusedItem.getItemWidth(availWidth, availWidth, availHeight) >> 1);
      if (this.referenceYCenterPositions != null) {
        this.focusedItem.relativeY =
            this.referenceYCenterPositions[this.focusedIndex]
                - (this.focusedItem.getItemHeight(availWidth, availWidth, availHeight) >> 1);
      }
      //			System.out.println("focused.relativeX=" + this.focusedItem.relativeX);
      this.focusedStyle = null;
    }

    this.contentWidth = availWidth; // TODO: this can change when no expanded layout is used
    this.contentHeight =
        this.focusedLabel == null
            ? maxHeight
            : maxHeight
                + this.focusedLabel.getItemHeight(
                    availWidth,
                    availWidth,
                    availHeight); // maxItemHeight + this.paddingVertical +
                                  // this.focusedLabel.getItemHeight(lineWidth, lineWidth);

    if (!this.isFocused) {
      AnimationThread.addAnimationItem(parent);
    }
  }
  /* (non-Javadoc)
   * @see de.enough.polish.ui.ItemView#animate(long, de.enough.polish.ui.ClippingRegion)
   */
  public void animate(long currentTime, ClippingRegion repaintRegion) {
    super.animate(currentTime, repaintRegion);

    synchronized (this.lock) {
      // #if polish.midp2
      if (this.shownRgbDataWidths == null) {
        // #debug warn
        de.enough.polish.util.Debug.debug(
            "warn",
            "de.enough.polish.ui.containerviews.FishEyeContainerView",
            158,
            "FishEyeContainerView is animated before initContent has been called");
        return;
      }
      // #endif

      boolean animated = false;
      if (this.targetXCenterPositions != null) {
        Item[] myItems = this.parentContainer.getItems();
        int length = myItems.length;
        // #if polish.css.fisheyeview-max-visible
        // # int maxDistance = length;
        // # if (this.maxVisibleItems != 0) {
        // # maxDistance = this.maxVisibleItems >> 1;
        // # }
        // #endif
        for (int i = 0; i < length; i++) {
          int target = this.targetXCenterPositions[i];
          Item item = myItems[i];
          int halfItemWidth = (item.itemWidth >> 1);
          int distance = getDistance(i, this.focusedIndex, length);
          if (distance != 0) {
            distance--;
          }
          // #if polish.midp2
          int factor = this.scaleFactor;
          // #endif
          // #if tmp.scaleAll
          // # factor = factor + ((this.scaleFactorEnd - factor ) * distance) / (length >> 1);
          // #endif
          // #if polish.midp2
          if (i != this.focusedIndex) {
            halfItemWidth = (halfItemWidth * factor) / 100;
          }
          // #endif
          int current = item.relativeX + halfItemWidth;
          // System.out.println("animate: itemWidth of " + i + " with distance " + distance + " =" +
          // halfItemWidth);
          // System.out.println(i + ": current=" + current + ", target=" + target);
          if (current != target) {
            animated = true;
            // System.out.println(i + ": animate:  with distance " + distance + ", halfItemWidth=" +
            // halfItemWidth + ", current=" + current + ", target=" + target + ", focusedIndex=" +
            // this.focusedIndex);
            item.relativeX = calculateCurrent(current, target) - halfItemWidth;
            // System.out.println( i + ": relativeX=" + item.relativeX);
          }
          if (this.targetYCenterPositions != null) {
            int halfItemHeight = (item.itemHeight >> 1);
            // #if polish.midp2
            if (i != this.focusedIndex) {
              halfItemHeight = (halfItemHeight * factor) / 100;
            }
            // #endif
            current = item.relativeY + halfItemHeight;
            target = this.targetYCenterPositions[i];
            if (current != target) {
              animated = true;
              item.relativeY = calculateCurrent(current, target) - halfItemHeight;
            }
          }
          // #if polish.css.fisheyeview-max-visible
          // # if (distance >= maxDistance ) {
          // # continue;
          // # }
          // #endif
          // #if polish.midp2
          int currentAlpha = this.currentTranslucencies[i];
          int targetAlpha = this.targetTranslucencies[i];
          boolean adjustAlpha = (currentAlpha != targetAlpha);
          if (adjustAlpha) {
            currentAlpha = calculateCurrent(currentAlpha, targetAlpha);
            this.currentTranslucencies[i] = currentAlpha;
          }
          boolean isScaled = false;
          if (factor != 100) {
            current = this.shownRgbDataWidths[i];
            if (i == this.focusedIndex) {
              target = this.originalRgbDataWidths[i];
            } else {
              target = (this.originalRgbDataWidths[i] * factor) / 100;
            }
            if (current != target
                && (distance < (length >> 2)
                    || i == this.focusedIndex
                    || (Math.abs(current - target) * 100 / target > 5))) {
              animated = true;
              isScaled = true;
              int[] data = this.originalRgbData[i];
              int originalWidth = this.originalRgbDataWidths[i];
              int originalHeight = data.length / originalWidth;
              int newWidth = calculateCurrent(current, target);
              int newHeight = (newWidth * originalHeight) / originalWidth;
              // int alpha = calculateAlpha( getDistance( i, this.focusedIndex, length ), length );
              // this.shownRgbData[i] = ImageUtil.scale(alpha, data, newWidth, newHeight,
              // originalWidth, originalHeight );
              // #if polish.FishEye.scaleHq
              // # ImageUtil.scaleDownHq(this.shownRgbData[i],data, originalWidth, newWidth, 0,
              // currentAlpha, false);
              // #else
              ImageUtil.scale(
                  currentAlpha,
                  data,
                  newWidth,
                  newHeight,
                  originalWidth,
                  originalHeight,
                  this.shownRgbData[i]);
              // #endif
              this.shownRgbDataWidths[i] = newWidth;
              this.shownRgbDataHeights[i] = newHeight;
              // item.itemWidth = newWidth;
              // item.itemHeight = newHeight;
              // item.relativeX += (originalWidth - newWidth) >> 1;
              // System.out.println("animate: new item width of " + i + " = " + newWidth + ",
              // difference=" + (originalWidth - newWidth));
            }
          }
          if (adjustAlpha && !isScaled) {
            // adjust only the translucency:
            animated = true;
            int[] rgbData = this.shownRgbData[i];
            if (rgbData != null) {
              ImageUtil.setTransparencyOnlyForOpaque(currentAlpha, rgbData, true);
            }
          }
          // #endif
        }
      }
      if (this.isRemoveText && this.focusedLabel != null) {
        animated |= this.focusedLabel.animate();
      }
      if (this.focusedBackground != null) {
        animated |= this.focusedBackground.animate();
      }
      if (animated) {
        repaintRegion.addRegion(
            this.parentContainer.getAbsoluteX() - 10,
            this.parentContainer.getAbsoluteY() - 10,
            this.parentContainer.itemWidth + 20,
            this.parentContainer.itemHeight + 20);
      }
    }
  }
  /* (non-Javadoc)
   * @see de.enough.polish.ui.ContainerView#focusItem(int, de.enough.polish.ui.Item, int, de.enough.polish.ui.Style)
   */
  public Style focusItem(int focIndex, Item item, int direction, Style focStyle) {
    if (this.referenceXCenterPositions == null
        || this.referenceXCenterPositions.length != this.parentContainer.size()) {
      this.focusedStyle = focStyle;
      this.focusedDirection = direction;
      this.focusedIndex = focIndex;
      this.focusedItem = item;
      return item.getStyle();
    } else {
      int difference = this.referenceFocusedIndex - focIndex;
      Item[] myItems = this.parentContainer.getItems();
      int[] targetXPositions;
      int[] targetYPositions = null;
      if (this.targetXCenterPositions == null
          || this.targetXCenterPositions.length != myItems.length) {
        targetXPositions = new int[myItems.length];
        if (this.referenceYCenterPositions != null) {
          targetYPositions = new int[myItems.length];
        }
      } else {
        targetXPositions = this.targetXCenterPositions;
        if (this.referenceYCenterPositions != null) {
          targetYPositions = this.targetYCenterPositions;
        }
      }
      if (this.referenceXCenterPositions.length != targetXPositions.length) {
        return item.getStyle();
      }
      for (int i = 0; i < myItems.length; i++) {
        int nextIndex = i + difference;
        if (nextIndex < 0) {
          nextIndex = myItems.length + nextIndex;
        } else if (nextIndex >= myItems.length) {
          nextIndex -= myItems.length;
        }
        targetXPositions[i] = this.referenceXCenterPositions[nextIndex];
        if (targetYPositions != null) {
          targetYPositions[i] = this.referenceYCenterPositions[nextIndex];
        }
      }
      this.targetXCenterPositions = targetXPositions;
      if (targetYPositions != null) {
        this.targetYCenterPositions = targetYPositions;
      }
    }
    Style itemStyle;
    if (!item.isFocused) {
      itemStyle = super.focusItem(focIndex, item, direction, focStyle);
    } else {
      itemStyle = item.getStyle();
    }

    this.focusedBackground = removeItemBackground(item);
    this.focusedBorder = removeItemBorder(item);
    if (this.isRemoveText) {
      if (this.isShowTextInTitle) {
        Screen scr = getScreen();
        if (scr != null) {
          scr.setTitle(this.labels[focIndex]);
        }
      } else if (this.focusedLabel != null) {
        this.focusedLabel.setText(this.labels[focIndex]);
        if (this.focusedLabel.getStyle() != item.getStyle()) {
          this.focusedLabel.setStyle(item.getStyle());
          removeItemBackground(this.focusedLabel);
          removeItemBorder(this.focusedLabel);
        }
      }
    }
    return itemStyle;
  }
  /* (non-Javadoc)
   * @see de.enough.polish.ui.ContainerView#initContent(de.enough.polish.ui.Container, int, int)
   */
  protected void initContent(
      Item parentContainerItem, int firstLineWidth, int availWidth, int availHeight) {
    synchronized (this.lock) {
      this.isVertical = false;
      this.isHorizontal = true;
      Container parent = (Container) parentContainerItem;
      // #debug
      System.out.println(
          "CoverFlow: intialising content for "
              + this
              + " with vertical-padding "
              + this.paddingVertical);

      this.parentContainer = parent;
      Item[] myItems = parent.getItems();
      int length = myItems.length;
      if (this.focusedIndex == -1 && length != 0) {
        // this.parentContainer.focus(0);
        if (parent.focusedIndex != -1) {
          this.focusedIndex = parent.focusedIndex;
        } else {
          this.focusedIndex = 0;
        }
        // System.out.println("AUTO-FOCUSSING ITEM " + this.focusedIndex );
        this.focusedItem = myItems[this.focusedIndex];
        this.focusedStyle = this.focusedItem.getFocusedStyle();
      }
      if (this.referenceXCenterPositions != null
          && this.referenceXCenterPositions.length == length) {
        return;
      }

      // #if polish.css.show-text-in-title
      if (this.isRemoveText && this.focusedLabel == null && !this.isShowTextInTitle) {
        this.focusedLabel = new StringItem(null, null);
      }
      // #else
      if (this.isRemoveText && this.focusedLabel == null) {
        this.focusedLabel = new StringItem(null, null);
      }
      // #endif

      if (this.isRemoveText && (this.labels == null || this.labels.length != length)) {
        this.labels = new String[length];
      }

      int maxWidth = 0;
      int maxHeight = 0;
      boolean hasFocusableItem = false;
      // #if polish.midp2
      this.originalRgbData = new int[length][];
      this.originalRgbDataWidths = new int[length];
      this.shownRgbData = new int[length][];
      this.shownRgbDataWidths = new int[length];
      this.shownRgbDataHeights = new int[length];
      // #endif
      for (int i = 0; i < length; i++) {
        Item item = myItems[i];
        if (this.isRemoveText) {
          String text = item.getLabel();
          if (text != null) {
            this.labels[i] = text;
            item.setLabel(null);
          } else if (item instanceof IconItem) {
            IconItem iconItem = (IconItem) item;
            text = iconItem.getText();
            if (text != null) {
              this.labels[i] = text;
              iconItem.setTextVisible(false);
              // iconItem.setText(null);
            }
          }
        }
        int width = item.getItemWidth(firstLineWidth, availWidth, availHeight);
        int height = item.getItemHeight(firstLineWidth, availWidth, availHeight);
        // #if polish.midp2
        int[] data = UiAccess.getRgbData(item);
        this.originalRgbData[i] = data;
        this.originalRgbDataWidths[i] = width;
        if (this.scaleFactorWidth == 100) {
          this.shownRgbData[i] = data;
          this.shownRgbDataWidths[i] = width;
          this.shownRgbDataHeights[i] = height;
        } else {
          int newWidth = (width * this.scaleFactorWidth) / 100;
          int newHeightInner = (height * this.scaleFactorInnerHeight) / 100;
          int newHeightOuter = (height * this.scaleFactorOuterHeight) / 100;
          this.shownRgbData[i] = new int[data.length];
          if (isLeftOfFocus(i, this.focusedIndex, length)) {
            ImageUtil.perspectiveShear(
                data,
                this.shownRgbData[i],
                width,
                newWidth,
                newHeightOuter,
                newHeightInner,
                255,
                ImageUtil.EDGEDETECTION_MAP_FAST_AND_SIMPLE);
          } else {
            ImageUtil.perspectiveShear(
                data,
                this.shownRgbData[i],
                width,
                newWidth,
                newHeightInner,
                newHeightOuter,
                255,
                ImageUtil.EDGEDETECTION_MAP_FAST_AND_SIMPLE);
          }
          //					System.out.println("newWidth=" + newWidth);
          this.shownRgbDataWidths[i] = width;
          this.shownRgbDataHeights[i] = height;
        }
        // #endif
        if (item.appearanceMode != Item.PLAIN) {
          hasFocusableItem = true;
        }
        if (width > maxWidth) {
          maxWidth = width;
        }
        if (height > maxHeight) {
          maxHeight = height;
        }
      }
      this.maxItemHeight = maxHeight;
      if (hasFocusableItem) {
        this.appearanceMode = Item.INTERACTIVE;
      } else {
        this.appearanceMode = Item.PLAIN;
      }

      initItemArrangement(availWidth, myItems, length, maxWidth, maxHeight);

      // use reference positions to set the position for the items:
      for (int i = 0; i < length; i++) {
        Item item = myItems[i];
        int distance = getDistance(i, this.focusedIndex, length);
        if (distance != 0) {
          distance--;
        }
        int halfItemWidth = (item.getItemWidth(availWidth, availWidth, availHeight) >> 1);
        int halfItemHeight = (item.getItemHeight(availWidth, availWidth, availHeight) >> 1);
        // #if polish.midp2
        if (i != this.focusedIndex) {
          int factor = getScaleFactor(distance, length);
          halfItemWidth = (halfItemWidth * factor) / 100;
          halfItemHeight = (halfItemHeight * factor) / 100;
        }
        // #endif
        // System.out.println(i + ": initContent:  with distance " + distance + ", halfItemWidth=" +
        // halfItemWidth + ", focusedIndex=" + this.focusedIndex);
        item.relativeX = this.referenceXCenterPositions[i] - halfItemWidth;
        if (this.referenceYCenterPositions != null) {
          item.relativeY = this.referenceYCenterPositions[i] - halfItemHeight;
        }
        // System.out.println( i + ": relativeX=" + item.relativeX);

        //			System.out.println("item.relativeX for " + i + "=" + item.relativeX);
      }
      if (this.focusedStyle != null) {
        focusItem(this.focusedIndex, this.focusedItem, this.focusedDirection, this.focusedStyle);
        this.focusedItem.relativeX =
            this.referenceXCenterPositions[this.focusedIndex]
                - (this.focusedItem.getItemWidth(availWidth, availWidth, availHeight) >> 1);
        if (this.referenceYCenterPositions != null) {
          this.focusedItem.relativeY =
              this.referenceYCenterPositions[this.focusedIndex]
                  - (this.focusedItem.getItemHeight(availWidth, availWidth, availHeight) >> 1);
        }
        //			System.out.println("focused.relativeX=" + this.focusedItem.relativeX);
        this.focusedStyle = null;
      }

      this.contentWidth = availWidth; // TODO: this can change when no expanded layout is used
      this.contentHeight =
          this.focusedLabel == null
              ? maxHeight
              : maxHeight
                  + this.focusedLabel.getItemHeight(
                      availWidth,
                      availWidth,
                      availHeight); // maxItemHeight + this.paddingVertical +
      // this.focusedLabel.getItemHeight(lineWidth, lineWidth);

      if (!this.isFocused) {
        AnimationThread.addAnimationItem(parent);
      }
      animate(System.currentTimeMillis(), null);
    }
  }
  /* (non-Javadoc)
   * @see de.enough.polish.ui.ItemView#animate(long, de.enough.polish.ui.ClippingRegion)
   */
  public void animate(long currentTime, ClippingRegion repaintRegion) {
    super.animate(currentTime, repaintRegion);
    synchronized (this.lock) {
      // #if polish.midp2
      if (this.shownRgbDataWidths == null) {
        // #debug warn
        System.out.println("CoverFlowContainerView is animated before initContent has been called");
        return;
      }
      // #endif
      boolean animated = false;
      if (this.targetXCenterPositions != null) {
        Item[] myItems = this.parentContainer.getItems();
        int length = myItems.length;
        // #if polish.css.fisheyeview-max-visible
        int maxDistance = length;
        if (this.maxVisibleItems != 0) {
          maxDistance = this.maxVisibleItems >> 1;
        }
        // #endif
        for (int i = 0; i < length; i++) {
          int target = this.targetXCenterPositions[i];
          Item item = myItems[i];
          int halfItemWidth = (item.itemWidth >> 1);
          int distance = getDistance(i, this.focusedIndex, length);
          if (distance != 0) {
            distance--;
          }
          // #if polish.midp2
          int factor = this.scaleFactorWidth;
          // #endif
          // #if polish.midp2
          if (i != this.focusedIndex) {
            halfItemWidth = (halfItemWidth * factor) / 100;
          }
          // #endif
          int current = item.relativeX + halfItemWidth;
          boolean scaleInAnyCase = false;
          // System.out.println("animate: itemWidth of " + i + " with distance " + distance + " =" +
          // halfItemWidth);
          // System.out.println(i + ": current=" + current + ", target=" + target);
          if (current != target) {
            if (Math.abs(current - target) > item.itemWidth) {
              scaleInAnyCase = true;
            }
            animated = true;
            // System.out.println(i + ": animate:  with distance " + distance + ", halfItemWidth=" +
            // halfItemWidth + ", current=" + current + ", target=" + target + ", focusedIndex=" +
            // this.focusedIndex);
            item.relativeX = calculateCurrent(current, target) - halfItemWidth;
            // System.out.println( i + ": relativeX=" + item.relativeX);
          }
          if (this.targetYCenterPositions != null) {
            int halfItemHeight = (item.itemHeight >> 1);
            // #if polish.midp2
            if (i != this.focusedIndex) {
              halfItemHeight = (halfItemHeight * factor) / 100;
            }
            // #endif
            current = item.relativeY + halfItemHeight;
            target = this.targetYCenterPositions[i];
            if (current != target) {
              animated = true;
              item.relativeY = calculateCurrent(current, target) - halfItemHeight;
            }
          }
          // #if polish.css.fisheyeview-max-visible
          if (distance >= maxDistance) {
            continue;
          }
          // #endif
          // #if polish.midp2
          boolean isLeft = current < target;
          current = this.shownRgbDataWidths[i];
          if (i == this.focusedIndex) {
            target = this.originalRgbDataWidths[i];
          } else {
            target = (this.originalRgbDataWidths[i] * factor) / 100;
          }
          if (current != target || scaleInAnyCase) {
            animated = true;
            int[] data = this.originalRgbData[i];
            int originalWidth = this.originalRgbDataWidths[i];
            int newWidth = calculateCurrent(current, target);
            int height = item.itemHeight;
            int newHeightInner;
            int newHeightOuter;
            if (i == this.focusedIndex) {
              newHeightInner =
                  (height
                          * (this.scaleFactorInnerHeight
                              + ((current * (100 - this.scaleFactorInnerHeight)) / target)))
                      / (100);
              newHeightOuter =
                  (height
                          * (this.scaleFactorOuterHeight
                              + ((current * (100 - this.scaleFactorOuterHeight)) / target)))
                      / (100);
            } else {
              newHeightInner =
                  (height * (100 - ((current * (100 - this.scaleFactorInnerHeight)) / target)))
                      / (100);
              newHeightOuter =
                  (height * (100 - ((current * (100 - this.scaleFactorOuterHeight)) / target)))
                      / (100);
            }
            if (newHeightInner > height) {
              newHeightInner = height;
            }
            if (newHeightOuter > height) {
              newHeightOuter = height;
            }
            // this.shownRgbDataWidths[i] = newWidth;

            if ((i == this.focusedIndex && isLeft) || isLeftOfFocus(i, this.focusedIndex, length)) {
              ImageUtil.perspectiveShear(
                  data,
                  this.shownRgbData[i],
                  originalWidth,
                  newWidth,
                  newHeightOuter,
                  newHeightInner,
                  255,
                  ImageUtil.EDGEDETECTION_MAP_FAST_AND_SIMPLE);
            } else {
              ImageUtil.perspectiveShear(
                  data,
                  this.shownRgbData[i],
                  originalWidth,
                  newWidth,
                  newHeightInner,
                  newHeightOuter,
                  255,
                  ImageUtil.EDGEDETECTION_MAP_FAST_AND_SIMPLE);
            }
            // System.out.println("newWidth=" + newWidth + ", originalWidth=" + originalWidth);
          }
          // #endif
        }
      }
      if (this.isRemoveText && this.focusedLabel != null) {
        animated |= this.focusedLabel.animate();
      }
      if (this.focusedBackground != null) {
        animated |= this.focusedBackground.animate();
      }
      if (animated && repaintRegion != null) {
        repaintRegion.addRegion(
            this.parentContainer.getAbsoluteX() - 10,
            this.parentContainer.getAbsoluteY() - 10,
            this.parentContainer.itemWidth + 20,
            this.parentContainer.itemHeight + 20);
      }
    }
  }
  /* (non-Javadoc)
   * @see de.enough.polish.browser.TagHandler#handleTag(de.enough.polish.ui.Container, de.enough.polish.xml.PullParser, java.lang.String, boolean, de.enough.polish.util.HashMap, de.enough.polish.ui.Style)
   */
  public boolean handleTag(
      Container parentItem,
      SimplePullParser parser,
      String tagName,
      boolean opening,
      HashMap attributeMap,
      Style style) {
    // #debug
    System.out.println((opening ? "<" : "</") + tagName + ">");
    tagName = tagName.toLowerCase();
    if (TAG_DIV.equals(tagName) || TAG_SPAN.equals(tagName)) {
      if (opening) {
        String itemStyleName = (String) attributeMap.get("textclass");
        Style itemStyle = (itemStyleName == null ? null : StyleSheet.getStyle(itemStyleName));
        if (itemStyle != null) {
          this.textStyle = itemStyle;
        }
        if (this.isDivOrSpanOpened == null) {
          this.isDivOrSpanOpened = new BooleanStack();
        }
        //				System.out.println("opening <div> with style " + (style == null ? null : style.name));
        if (style != null) {
          this.browser.openContainer(style);
        }
        this.isDivOrSpanOpened.push(style != null);
        //				this.browser.openContainer( style );
        //				this.isDivOrSpanOpened.push( true );
      } else {
        this.textStyle = null;
        // System.out.println("closing <div> with container=" + this.isDivOrSpanOpened.peek());
        if (this.isDivOrSpanOpened.pop()) {
          Container container = this.browser.closeContainer();
          if (UiAccess.cast(container) instanceof TableItem) {
            this.currentTable = (TableItem) UiAccess.cast(container);
          }
        }
        //				Style divStyle = container.getStyle();
        //					if (divStyle != null) {
        //					Object[] items = container.getInternalArray();
        //					for (int i = 0; i < items.length; i++)
        //					{
        //						Item item = (Item) items[i];
        //						if (item == null) {
        //							break;
        //						}
        //						item.setStyle( divStyle );
        //					}
        //				}
      }
    } else if (TAG_SELECT.equals(tagName)) {
      if (opening) {
        if (this.currentSelect != null) {
          // #debug error
          System.out.println(
              "Error in HTML-Code: You cannot open a <select>-tag inside another <select>-tag.");

          ChoiceGroup choiceGroup = this.currentSelect.getChoiceGroup();
          add(choiceGroup);
          if (this.currentForm == null) {
            // #debug error
            System.out.println("Error in HTML-Code: no <form> for <select> element found!");
          } else {
            this.currentForm.addItem(choiceGroup);
          }
          this.currentSelect = null;
        }

        String name = parser.getAttributeValue(ATTR_NAME);
        String sizeStr = parser.getAttributeValue(ATTR_SIZE);
        int size;

        try {
          size = Integer.parseInt(sizeStr);
        } catch (NumberFormatException e) {
          size = -1;
        }

        boolean isMultiple = parser.getAttributeValue(ATTR_MULTIPLE) != null;
        this.currentSelect = new HtmlSelect(name, size, isMultiple, style);
      } else { // tag is closed
        if (this.currentSelect != null) {
          ChoiceGroup choiceGroup = this.currentSelect.getChoiceGroup();
          add(choiceGroup);
          if (this.currentForm == null) {
            // #debug error
            System.out.println("Error in HTML-Code: no <form> for <select> element found!");
          } else {
            this.currentForm.addItem(choiceGroup);
          }
          this.currentSelect = null;
        }
        // #mdebug error
        else {
          // #debug error
          System.out.println(
              "Error in HTML-Code. You cannot close a <select>-tag without opening one.");
        }
        // #enddebug
      }
      return true;
    } else if (TAG_OPTION.equals(tagName)) {
      if (this.currentSelect != null && opening) {
        // TODO: handle "selected" attribute.
        String value = parser.getAttributeValue(ATTR_VALUE);
        String selected = parser.getAttributeValue("selected");
        parser.next();
        String name = handleText(parser.getText());

        if (value == null) {
          value = name;
        }

        this.currentSelect.addOption(name, value, selected != null, style);
      }
      return true;
    } else if (TAG_A.equals(tagName)) {
      if (opening) {
        this.anchorHref = (String) attributeMap.get(ATTR_HREF);
        // #if polish.debug.error
        if (this.anchorHref == null) {
          // #debug error
          System.out.println(
              "Unable to handle anchor tag <a> without "
                  + ATTR_HREF
                  + " attribute: "
                  + attributeMap);
        }
        // #endif
        this.browser.openContainer(style);
        if (style == null) {
          Container container = this.browser.getCurrentContainer();
          // #style browserLink
          UiAccess.setStyle(container);
        }
      } else {
        // apply link to last item(s):
        Container container = this.browser.removeCurrentContainer();
        Style contStyle = container.getStyle();
        Item linkItem;
        if (container.size() == 0) {
          linkItem = new StringItem(null, null);
        } else if (container.size() == 1) {
          linkItem = container.get(0);
        } else {
          // check if all elements are StringItems - then we should combine them:
          boolean allItemsAreStringItems = true;
          StringBuffer text = new StringBuffer();
          for (int i = 0; i < container.size(); i++) {
            Item item = container.get(i);
            if (!(item instanceof StringItem)) {
              allItemsAreStringItems = false;
              break;
            } else {
              if (text.length() > 0) {
                text.append(' ');
              }
              text.append(((StringItem) item).getText());
            }
          }
          if (allItemsAreStringItems) {
            linkItem = new StringItem(null, text.toString());
          } else {
            linkItem = container;
          }
        }
        //				System.out.println("closing <a>: container.size()=" + container.size() + ", linkItem="
        // + linkItem + ", style=" + (contStyle != null ? contStyle.name : "<no style>") );
        if (this.anchorHref != null) {
          if (contStyle != null) {
            linkItem.setStyle(contStyle);
          } else if (linkItem.getStyle() == null) {
            // #style browserLink
            UiAccess.setStyle(linkItem);
          }
          linkItem.setDefaultCommand(CMD_LINK);
          linkItem.setItemCommandListener(this);
          linkItem.setAttribute(ATTR_HREF, this.anchorHref);
          addCommands(TAG_A, linkItem);
          add(linkItem);
        }

        // this.browser.closeContainer();
      }
    }

    if (opening) {
      //			if (TAG_A.equals(tagName))
      //			{
      //				String href = (String) attributeMap.get(ATTR_HREF);
      //				parser.next();
      //				Item linkItem;
      //				if (href != null)
      //				{
      //					String anchorText = handleText(parser.getText());
      //					// hack for image links:
      //					if ("".equals(anchorText) && TAG_IMG.equals(parser.getName())) {
      //						// this is an image link:
      //						attributeMap.clear();
      //						for (int i = 0; i < parser.getAttributeCount(); i++)
      //						{
      //							String attributeName = parser.getAttributeName(i);
      //							String attributeValue = parser.getAttributeValue(i);
      //							attributeMap.put(attributeName, attributeValue);
      //						}
      //						String src = (String) attributeMap.get("src");
      //						String url = this.browser.makeAbsoluteURL(src);
      //						Image image = this.browser.loadImage(url);
      //						//#style browserLink
      //						linkItem = new ImageItem(null, image, 0, (String) attributeMap.get("alt") );
      //						//this.browser.loadImageLater( url, (ImageItem) linkItem );
      //
      //					} else {
      //						//#style browserLink
      //						linkItem = new StringItem(null, anchorText);
      //					}
      //					linkItem.setDefaultCommand(CMD_LINK);
      //					linkItem.setItemCommandListener( this );
      //					linkItem.setAttribute(ATTR_HREF, href );
      //					addCommands(TAG_A, linkItem);
      //				}
      //				else
      //				{
      //					//#style browserText
      //					linkItem = new StringItem(null, handleText(parser.getText()));
      //				}
      //				if (style != null) {
      //					linkItem.setStyle(style);
      //				}
      //				add(linkItem);
      //				return true;
      //			}
      //			else
      if (TAG_BR.equals(tagName)) {
        addLineBreak();
        return true;
      } else if (TAG_P.equals(tagName)) {
        addLineBreak();
        if (opening) {
          this.textStyle = style;
        }
        return true;
      } else if (TAG_IMG.equals(tagName)) {
        String src = (String) attributeMap.get("src");
        String url = this.browser.makeAbsoluteURL(src);
        Dimension width = parseSizeValue((String) attributeMap.get("width"));
        Dimension height = parseSizeValue((String) attributeMap.get("height"));
        Style imageStyle = new Style();
        imageStyle.addAttribute(58 /* "min-width" */, width);
        imageStyle.addAttribute(144 /* "min-height" */, height);
        ImageItem item;

        if (width != null || height != null) {
          item = new ScaledImageItem(null, null, width, height, Item.LAYOUT_DEFAULT, "");
        } else {
          item = new ImageItem(null, null, Item.LAYOUT_DEFAULT, "");
        }

        if (imageStyle != null) {
          item.setStyle(imageStyle);
        }

        this.browser.loadImageLater(item, url);
        add(item);
        return true;
      } else if (TAG_TITLE.equals(tagName)) {
        // Hack to read title.
        parser.next();
        String name = handleText(parser.getText());
        Screen myScreen = this.browser.getScreen();
        if (name != null && myScreen != null) {
          myScreen.setTitle(name);
        }
        return true;
      } else if (TAG_STYLE.equals(tagName)) {
        // Hack to read style content.
        parser.next();
        String cssCode = parser.getText();
        try {
          CssInterpreter reader = new CssInterpreter(cssCode, this.browser);
          this.browser.setCssStyles(reader.getAllStyles());
        } catch (Exception e) {
          // #debug error
          System.out.println("Unable to parse CSS" + e);
        }
        // parser.next();
        return true;
      } else if (TAG_META.equals(tagName)) {
        String httpEquiv = (String) attributeMap.get("http-equiv");
        if (httpEquiv != null && TextUtil.equalsIgnoreCase("refresh", httpEquiv)) {
          String content = (String) attributeMap.get("content");
          if (content != null) {
            int semicolonPos = content.indexOf(';');
            int waitTime = 0;
            String url = content;
            if (semicolonPos != -1) {
              try {
                waitTime = Integer.parseInt(content.substring(0, semicolonPos));
                url = content.substring(semicolonPos + 1);
              } catch (Exception e) {
                if (semicolonPos == 0) {
                  url = content.substring(1);
                }
              }
            }
            int equalsPos = url.indexOf('=');
            if (equalsPos != -1) {
              url = url.substring(equalsPos + 1).trim();
            }
            if (url.indexOf(':') == -1) {
              // assuming resource protocol:
              if (url.charAt(0) != '/') {
                url = "resource://" + url;
              } else {
                url = "resource:/" + url;
              }
            }
            if (waitTime > 0) {
              (new RedirectThread(this.browser, waitTime * 1000L, url)).start();
            } else {
              // consume rest of document:
              while (parser.next() != SimplePullParser.END_DOCUMENT) {
                // read document..
              }
              this.browser.go(url);
            }
            return true;
          }
        }
        return false;
      }
      // #if polish.Browser.supportTextInput != false
      else if (TAG_TEXT_AREA.equals(tagName)) {
        parser.next();
        String value = handleText(parser.getText());
        int maxCharNumber = 500;
        String cols = (String) attributeMap.get("cols");
        String rows = (String) attributeMap.get("rows");
        if (cols != null && rows != null) {
          try {
            maxCharNumber = Integer.parseInt(cols) * Integer.parseInt(rows);
          } catch (Exception e) {
            // #debug error
            System.out.println(
                "Unable to parse textarea cols or rows attribute: cols=" + cols + ", rows=" + rows);
          }
        }
        // #style browserInput
        TextField textField = new TextField(null, value, maxCharNumber, TextField.ANY);
        if (style != null) {
          textField.setStyle(style);
        }
        add(textField);
        if (this.currentForm != null) {
          this.currentForm.addItem(textField);
          textField.setAttribute(ATTR_FORM, this.currentForm);
          String name = (String) attributeMap.get(INPUT_NAME);
          if (value == null) {
            value = name;
          }
          if (name != null) {
            textField.setAttribute(ATTR_NAME, name);
            textField.setAttribute(ATTR_VALUE, value);
          }
        }
        return true;
      }
      // #endif
      else if (TAG_BUTTON.equals(tagName) && this.currentForm != null) {
        String name = (String) attributeMap.get(INPUT_NAME);
        String value = (String) attributeMap.get(INPUT_VALUE);

        if (value == null) {
          value = name;
        }

        // #style browserLink
        StringItem buttonItem = new StringItem(null, value);
        if (style != null) {
          buttonItem.setStyle(style);
        }
        buttonItem.setDefaultCommand(CMD_SUBMIT);
        buttonItem.setItemCommandListener(this);
        addCommands(TAG_INPUT, INPUT_TYPE, INPUTTYPE_SUBMIT, buttonItem);
        add(buttonItem);

        this.currentForm.addItem(buttonItem);
        buttonItem.setAttribute(ATTR_FORM, this.currentForm);
        buttonItem.setAttribute(ATTR_TYPE, "submit");

        if (name != null) {
          buttonItem.setAttribute(ATTR_NAME, name);
          buttonItem.setAttribute(ATTR_VALUE, value);
        }
      } else if (TAG_INPUT.equals(tagName)) {
        if (this.currentForm != null) {
          String type = (String) attributeMap.get(INPUT_TYPE);
          String name = (String) attributeMap.get(INPUT_NAME);
          String value = (String) attributeMap.get(INPUT_VALUE);
          if (type != null) {
            type = type.toLowerCase();
          }

          if (this.formListener != null && name != null) {
            value =
                this.formListener.verifyInitialFormValue(this.currentForm.getAction(), name, value);
          }
          // #if polish.Browser.supportTextInput != false
          if (INPUTTYPE_TEXT.equals(type)
              || INPUTTYPE_PASSWORD.equals(type)
              || INPUTTYPE_NUMERIC.equals(type)) {
            int constraints;
            if (INPUTTYPE_NUMERIC.equals(type)) {
              constraints = TextField.NUMERIC;
            } else {
              constraints = INPUTTYPE_TEXT.equals(type) ? TextField.ANY : TextField.PASSWORD;
            }
            // #style browserInput
            TextField textField =
                new TextField((String) attributeMap.get("label"), value, 100, constraints);
            if (style != null) {
              textField.setStyle(style);
            }
            add(textField);

            this.currentForm.addItem(textField);
            textField.setAttribute(ATTR_FORM, this.currentForm);

            if (name != null) {
              textField.setAttribute(ATTR_NAME, name);
              if (value == null) {
                value = "";
              }
              textField.setAttribute(ATTR_VALUE, value);
            }
          } else
          // #endif
          if (INPUTTYPE_SUBMIT.equals(type)) {

            if (value == null) {
              value = name;
            }

            // #style browserLink
            StringItem buttonItem = new StringItem((String) attributeMap.get("label"), value);
            if (style != null) {
              buttonItem.setStyle(style);
            }
            buttonItem.setDefaultCommand(CMD_SUBMIT);
            buttonItem.setItemCommandListener(this);
            addCommands(TAG_INPUT, INPUT_TYPE, INPUTTYPE_SUBMIT, buttonItem);
            add(buttonItem);

            this.currentForm.addItem(buttonItem);
            buttonItem.setAttribute(ATTR_FORM, this.currentForm);
            buttonItem.setAttribute(ATTR_TYPE, "submit");

            if (name != null) {
              buttonItem.setAttribute(ATTR_NAME, name);
              buttonItem.setAttribute(ATTR_VALUE, value);
            }
          } else if (INPUTTYPE_HIDDEN.equals(type)) {
            this.currentForm.addHiddenElement(name, value);
          } else if (INPUTTYPE_CHECKBOX.equals(type) || INPUTTYPE_RADIO.equals(type)) {
            boolean isCheckBox = INPUTTYPE_CHECKBOX.equals(type);
            parser.next();
            String label = parser.getText().trim();
            int labelLength = label.length();
            if (labelLength == 0) {
              parser.next();
              label = parser.getText().trim();
              labelLength = label.length();
            }
            if ((labelLength > 0) && label.charAt(labelLength - 1) == '\n') {
              label = label.substring(0, labelLength - 1);
            }
            ChoiceGroup choiceGroup;
            if (isCheckBox) {
              choiceGroup = this.currentCheckBoxChoiceGroup;
            } else {
              choiceGroup = this.currentRadioChoiceGroup;
            }
            if (choiceGroup == null || !name.equals(choiceGroup.getAttribute(ATTR_NAME))) {
              // create a new choice group:
              String groupLabel = (String) attributeMap.get("label");
              if (isCheckBox) {
                // #style browserChoiceGroupMultiple
                choiceGroup = new ChoiceGroup(groupLabel, Choice.MULTIPLE);
              } else {
                String choiceType = (String) attributeMap.get("choice");
                if ("popup".equals(choiceType)) {
                  // #style browserChoiceGroupPopup
                  choiceGroup = new ChoiceGroup(groupLabel, Choice.POPUP);
                  this.currentRadioChoiceGroup = choiceGroup;
                } else {
                  // #style browserChoiceGroupExclusive
                  choiceGroup = new ChoiceGroup(groupLabel, Choice.EXCLUSIVE);
                  this.currentRadioChoiceGroup = choiceGroup;
                }
              }
              choiceGroup.setAttribute(ATTR_NAME, name);
              String styleName = (String) attributeMap.get("groupclass");
              if (styleName != null) {
                Style groupStyle = StyleSheet.getStyle(styleName);
                if (groupStyle != null) {
                  choiceGroup.setStyle(groupStyle);
                }
              }
              add(choiceGroup);
              if (this.currentForm == null) {
                // #debug error
                System.out.println("Error in HTML-Code: no <form> for <select> element found!");
              } else {
                this.currentForm.addItem(choiceGroup);
              }
              // end of creating a new choice group
            }
            ChoiceItem item;
            if (isCheckBox) {
              // #style browserCheckBox
              item = new ChoiceItem(label, null, Choice.MULTIPLE);
            } else {
              // #style browserRadio
              item = new ChoiceItem(label, null, choiceGroup.getType());
            }
            item.setAttribute(ATTR_VALUE, value);
            choiceGroup.append(item);
            if (attributeMap.get("checked") != null) {
              choiceGroup.setSelectedIndex(choiceGroup.size() - 1, true);
            }
            if (style != null) {
              item.setStyle(style);
            }
          }
          // #if polish.debug.debug
          else {
            // #debug
            System.out.println("unhandled html form input type: " + type);
          }
          // #endif
        }

        return true;
      } else if (TAG_SCRIPT.equals(tagName)) {
        // Consume javascript code.
        parser.next();
        return true;
      } else if (TAG_TABLE.equals(tagName)) {
        // #style browserTable?
        TableItem table = new TableItem();
        table.setSelectionMode(
            TableItem.SELECTION_MODE_CELL | TableItem.SELECTION_MODE_INTERACTIVE);
        table.setCellContainerStyle(this.browser.getStyle());
        if (style != null) {
          table.setStyle(style);
        }

        this.currentTable = table;
        this.browser.openContainer(table);
        return true;
      } else if (this.currentTable != null && TAG_TR.equals(tagName)) {
        this.currentTable.moveToNextRow();
        return true;
      } else if (this.currentTable != null && TAG_TH.equals(tagName)) {
        // TODO differentiate between th and td
        this.currentTable.moveToNextColumn();
        return true;
      } else if (this.currentTable != null && TAG_TD.equals(tagName)) {
        // TODO differentiate between th and td
        this.currentTable.moveToNextColumn();
        return true;
      } else if (TAG_CODE.equals(tagName)) {
        // #if polish.css.style.browsertextcode && !polish.LibraryBuild
        // #style browserTextCode
        // # this.textStyle = ();
        // #endif
      }
    } else {
      // the tag is being closed:
      if (TAG_TABLE.equals(tagName)) {
        Container container = this.browser.closeContainer();
        if (UiAccess.cast(container) instanceof TableItem) {
          this.currentTable = (TableItem) UiAccess.cast(container);
        } else {
          this.currentTable = null;
        }
        return true;
      }
      if (TAG_CODE.equals(tagName)) {
        this.textStyle = null;
      }
    }

    if (TAG_B.equals(tagName) || TAG_STRONG.equals(tagName)) {
      this.textBold = opening;
      return true;
    } else if (TAG_I.equals(tagName) || TAG_EM.equals(tagName)) {
      this.textItalic = opening;
      return true;
    } else if (TAG_FORM.equals(tagName)) {
      if (opening) {
        String name = (String) attributeMap.get("name");
        String action = (String) attributeMap.get("action");
        String method = (String) attributeMap.get("method");
        String encoding = (String) attributeMap.get("enctype");

        if (method == null) {
          method = "GET";
        }
        this.currentForm =
            new HtmlForm(name, action, method, encoding, this.browser, this.formListener);
        this.browser.addForm(this.currentForm);
        this.browser.openContainer(style);
      } else {
        this.browser.closeContainer();
        this.currentForm = null;
        this.currentCheckBoxChoiceGroup = null;
        this.currentRadioChoiceGroup = null;
      }

      return true;
    } else if (opening && TAG_BODY.equals(tagName)) {
      if (style != null) {
        // System.out.println("applying style " + style.name + " for body with bg=" +
        // style.background);
        this.browser.setBackground(style.background);
        this.browser.setBorder(style.border);
        this.browser.setStyle(style, false);
      }
    }

    return false;
  }