@Override
      public void step1() {
        txt = content.getValue().toString();
        txt = txt.trim();
        if (txt.length() < 5) {
          Notification.show(
              "Card not played.",
              "Your message is too short to be useful.",
              Notification.Type.ERROR_MESSAGE);
          doNotAdvanceSteps(); // come into step1 again next time
          return;
        }
        if (txt.length() > 140) {
          Notification.show(
              "Card not played.", "Only 140 characters please.", Notification.Type.ERROR_MESSAGE);
          doNotAdvanceSteps(); // come into step1 again next time
          return;
        }

        // Admins get to add cards under other names
        author = Mmowgli2UI.getGlobals().getUserTL();
        if (author.isAdministrator()) adminSwitchAuthorsTL(event.getButton(), this);
        else run(); // does not need to suspend, so "continues" and executes step2
        // in the same clicklistener thread
      }
 public static CardSummaryListHeader newCardSummaryListHeader(
     CardType ct, boolean mockupOnly, Card parent) {
   CardSummaryListHeader lstHdr = new CardSummaryListHeader(ct.getId(), mockupOnly, parent);
   MmowgliSessionGlobals globs = Mmowgli2UI.getGlobals();
   lstHdr.bckgrndResource = globs.mediaLocator().getCardSummaryListHeaderBackground(ct);
   lstHdr.drawerResource = globs.mediaLocator().getCardSummaryDrawerBackground(ct);
   return lstHdr;
 }
  private void handleNoCreate(String msg) {
    if (!markedAsNoCreate) {
      markedAsNoCreate = true;
      if (msg == null) {
        MmowgliSessionGlobals globs = Mmowgli2UI.getGlobals();
        setTooltip(globs.whyCantCreateCard(ct.isIdeaCard()));
      } else setTooltip(msg);

      CardSummaryListHeader.this.removeStyleName("m-cursor-pointer");
      title.removeStyleName("m-cursor-pointer");
      content.removeStyleName("m-cursor-pointer");
    }
  }
    @SuppressWarnings("serial")
    @HibernateRead
    private void adminSwitchAuthorsTL(Button butt, final CardPlayHandler coroutine) {
      ArrayList<User> meLis = new ArrayList<User>(1);
      meLis.add(coroutine.author);
      User me = User.getTL(Mmowgli2UI.getGlobals().getUserID());

      final AddAuthorDialog dial = new AddAuthorDialog(meLis, true);
      StringBuilder sb = new StringBuilder("As adminstrator, <b>");
      sb.append(me.getUserName());
      sb.append("</b>, you may choose another player to be card author.");
      dial.infoLabel.setValue(sb.toString());
      dial.setCaption("Select Proxy Author");
      dial.setMultiSelect(false);
      dial.cancelButt.setCaption("Use myself");
      dial.addButt.setCaption("Use selected");

      // Rearrange buttons, add real cancel butt.
      // -------------------
      HorizontalLayout buttonHL = dial.getButtonHorizontalLayout();
      Iterator<Component> itr = buttonHL.iterator();
      Vector<Component> v = new Vector<Component>();
      while (itr.hasNext()) {
        Component component = itr.next();
        if (component instanceof Button) v.add(component);
      }
      buttonHL.removeAllComponents();
      itr = v.iterator();
      while (itr.hasNext()) {
        buttonHL.addComponent(itr.next());
      }
      Label sp = null;
      buttonHL.addComponent(sp = new Label());
      sp.setWidth("1px");
      buttonHL.setExpandRatio(sp, 1.0f);

      Button cancelButt = null;
      buttonHL.addComponent(cancelButt = new Button("Cancel"));
      cancelButt.addClickListener(
          new ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
              UI.getCurrent().removeWindow(dial); // dial.getParent().removeWindow(dial);
              coroutine.resetCoroutine();
            }
          });
      // -------------------

      dial.selectItemAt(0);
      dial.addListener(
          new CloseListener() {
            @Override
            @MmowgliCodeEntry
            @HibernateOpened
            @HibernateClosed
            @HibernateUserRead
            public void windowClose(CloseEvent e) {
              HSess.init();
              if (dial.addClicked) {
                Object o = dial.getSelected();

                if (o instanceof User) {
                  coroutine.author = (User) o;
                } else if (o instanceof QuickUser) {
                  QuickUser qu = (QuickUser) o;
                  coroutine.author = User.getTL(qu.id);
                }
              }
              coroutine.run(); // finish up
              HSess.close();
            }
          });

      UI.getCurrent().addWindow(dial);
      dial.center();
    }
 private boolean checkNoCreateBecauseHiddenTL(Card c) {
   if (c == null) return false; // ok to create
   User me = Mmowgli2UI.getGlobals().getUserTL();
   return c.isHidden() && !me.isGameMaster();
 }
  @SuppressWarnings("serial")
  @Override
  public void initGui() {
    addStyleName("m-cursor-pointer");
    if (bckgrndResource != null) {
      Embedded bkgnd = new Embedded(null, bckgrndResource);
      addComponent(bkgnd, "top:0px;left:0px");
    }
    final MmowgliSessionGlobals globs = Mmowgli2UI.getGlobals();
    ct = CardType.getTL(ctId);
    String textColorStyle = CardStyler.getCardTextColorOverBaseStyle(ct);

    // nested abslay for the click handler
    AbsoluteLayout topHalfLay = new AbsoluteLayout();
    topHalfLay.setWidth(CARDLISTHEADER_W);
    topHalfLay.setHeight(HEIGHT_NODRAWER);
    addComponent(topHalfLay, "top:0px;left:0px");

    title.setValue(ct.getTitle()); // .toUpperCase());
    title.setHeight(CARDLISTHEADER_TITLE_H);
    title.setWidth(CARDLISTHEADER_TITLE_W);
    title.addStyleName("m-cardsummarylist-header-title");
    title.addStyleName("m-cursor-pointer");
    title.addStyleName("m-vagabond-font");
    if (textColorStyle != null) title.addStyleName(textColorStyle);

    topHalfLay.addComponent(title, CARDLISTHEADER_TITLE_POS);

    content.setValue(ct.getPrompt());
    content.setHeight(CARDLISTHEADER_CONTENT_H);
    content.setWidth(CARDLISTHEADER_CONTENT_W);
    content.addStyleName("m-cardsummarylist-header-content");
    content.addStyleName("m-cursor-pointer");
    if (textColorStyle != null) content.addStyleName(textColorStyle);
    // cause exception w/ 2 windows?

    content.setId(CardDebug.getCardCreateClickDebugId(ct));
    topHalfLay.addComponent(content, CARDLISTHEADER_CONTENT_POS);

    boolean cantCreateBecauseHiddenParent = checkNoCreateBecauseHiddenTL(parent);
    boolean cantCreateBecauseParentMarkedNoChild =
        false; // todo enable with gameswitch checkNoCreateBecauseParentMarkedNoChild(parent);

    if (globs.canCreateCard(ct.isIdeaCard())) {
      markedAsNoCreate = false;
      if (!cantCreateBecauseHiddenParent && !cantCreateBecauseParentMarkedNoChild) {
        // Add the text at the bottom
        Label lab;
        topHalfLay.addComponent(lab = new Label("click to add new"), "top:130px;left:75px");
        lab.addStyleName("m-click-to-add-new");
        if (textColorStyle != null) lab.addStyleName(textColorStyle);
      }
    } else markedAsNoCreate = true;

    drawerComponent = new BuilderDrawer();
    addComponent(drawerComponent, CARDLISTHEADER_DRAWER_POS);
    drawerComponent.setVisible(false);

    setWidth(CARDLISTHEADER_W);
    setHeight(HEIGHT_NODRAWER);

    if (!mockupOnly)
      topHalfLay.addLayoutClickListener(
          new LayoutClickListener() {
            @Override
            @MmowgliCodeEntry
            @HibernateOpened
            @HibernateClosed
            public void layoutClick(LayoutClickEvent event) {
              HSess.init();
              if (checkNoCreateBecauseHiddenTL(
                  parent)) { // todo enable with game switch ||
                             // checkNoCreateBecauseParentMarkedNoChild(parent)) {
                if (drawerComponent.isVisible()) closeDrawer();
                HSess.close();
                return;
              }

              if (drawerComponent.isVisible()) closeDrawer();
              else {
                CardPermission cp = globs.cardPermissionsCommon(ct.isIdeaCard());
                if (!cp.canCreate) {
                  if (!markedAsNoCreate) handleNoCreate();
                  Notification.show(cp.whyNot);
                } else {
                  showDrawer();
                  handleCanCreate(); // reset tt, etc.
                  if (newCardListener != null) newCardListener.drawerOpenedTL(ctId);
                }
              }
              HSess.close();
            }
          });
    if (cantCreateBecauseHiddenParent) handleNoCreate("Can't add card to hidden parent");
    else if (cantCreateBecauseParentMarkedNoChild)
      handleNoCreate("New child cards cannot be added to this card");
    else if (!globs.canCreateCard(ct.isIdeaCard())) handleNoCreate();
    else setTooltip("Click to add card");
  }
  @HibernateSessionThreadLocalConstructor
  @SuppressWarnings("serial")
  public MapGameDesignPanel(GameDesignGlobals globs) {
    super(false, globs);
    Game g = Game.getTL();
    TextArea titleTA;
    final Serializable uid = Mmowgli2UI.getGlobals().getUserID();

    titleTA = (TextArea) addEditLine("Map Title", "Game.mapTitle", g, g.getId(), "MapTitle").ta;
    titleTA.setValue(g.getMapTitle());
    titleTA.setRows(1);

    latTA = addEditLine("Map Initial Latitude", "Game.mmowgliMapLatitude");
    boolean lastRO = latTA.isReadOnly();
    latTA.setReadOnly(false);
    latTA.setValue("" + g.getMapLatitude());
    latTA.setRows(1);
    latTA.setReadOnly(lastRO);
    latTA.addValueChangeListener(
        new Property.ValueChangeListener() {
          @Override
          @MmowgliCodeEntry
          @HibernateOpened
          @HibernateClosed
          public void valueChange(ValueChangeEvent event) {
            HSess.init();
            try {
              String val = event.getProperty().getValue().toString();
              double lat = Double.parseDouble(val);
              Game g = Game.getTL();
              g.setMapLatitude(lat);
              Game.updateTL();
              GameEventLogger.logGameDesignChangeTL("Map latitude", val, uid);
            } catch (Exception ex) {
              new Notification(
                      "Parameter error",
                      "<html>Check for proper decimal format.</br>New value not committed.",
                      Notification.Type.WARNING_MESSAGE,
                      true)
                  .show(Page.getCurrent());
            }
            HSess.close();
          }
        });

    lonTA = addEditLine("Map Initial Longitude", "Game.mmowgliMapLongitude");
    lastRO = lonTA.isReadOnly();
    lonTA.setReadOnly(false);
    lonTA.setValue("" + g.getMapLongitude());
    lonTA.setRows(1);
    lonTA.setReadOnly(lastRO);
    lonTA.addValueChangeListener(
        new Property.ValueChangeListener() {
          @Override
          @MmowgliCodeEntry
          @HibernateOpened
          @HibernateClosed
          public void valueChange(ValueChangeEvent event) {
            // System.out.println("lon valueChange");
            HSess.init();
            try {
              String val = event.getProperty().getValue().toString();
              double lon = Double.parseDouble(val);
              Game g = Game.getTL();
              g.setMapLongitude(lon);
              Game.updateTL();
              GameEventLogger.logGameDesignChangeTL("Map longitude", val, uid);
            } catch (Exception ex) {
              new Notification(
                      "Parameter error",
                      "<html>Check for proper decimal format.</br>New value not committed.",
                      Notification.Type.WARNING_MESSAGE,
                      true)
                  .show(Page.getCurrent());
            }
            HSess.close();
          }
        });

    zoomTA = addEditLine("Map Initial Zoom", "Game.mmowgliMapZoom");
    lastRO = zoomTA.isReadOnly();
    zoomTA.setReadOnly(false);
    zoomTA.setValue("" + g.getMapZoom());
    zoomTA.setRows(1);
    zoomTA.setReadOnly(lastRO);
    zoomTA.addValueChangeListener(
        new Property.ValueChangeListener() {
          @Override
          @MmowgliCodeEntry
          @HibernateOpened
          @HibernateClosed
          public void valueChange(ValueChangeEvent event) {
            HSess.init();
            try {
              String val = event.getProperty().getValue().toString();
              int zoom = Integer.parseInt(val);
              Game g = Game.getTL();
              g.setMapZoom(zoom);
              Game.updateTL();
              GameEventLogger.logGameDesignChangeTL("Map zoom", val, uid);
            } catch (Exception ex) {
              new Notification(
                      "Parameter error",
                      "Check for proper integer format.</br>New value not committed.",
                      Notification.Type.WARNING_MESSAGE,
                      true)
                  .show(Page.getCurrent());
            }
            HSess.close();
          }
        });
    Button b;
    this.addComponentLine(
        b = new Button("Set to generic Mmowgli Map Defaults", new MapDefaultSetter()));
    b.setEnabled(!globs.readOnlyCheck(false));
  }
 @Override
 protected void testButtonClickedTL(ClickEvent ev) {
   AppEvent evt = new AppEvent(MmowgliEvent.MAPCLICK, this, null);
   Mmowgli2UI.getGlobals().getController().miscEventTL(evt);
 }