Android Open Source - DragonGoApp Go Js Activity






From Project

Back to project page DragonGoApp.

License

The source code is released under:

GNU General Public License

If you think the Android project DragonGoApp listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package fr.xtof54.jsgo;
/*from   www .  j a  v a 2s.  co m*/
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;

import org.json.JSONException;
import org.json.JSONObject;

import fr.xtof54.dragonGoApp.R;
import fr.xtof54.jsgo.EventManager.eventType;
import fr.xtof54.jsgo.ServerConnection.DetLogger;
import android.net.TrafficStats;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.os.Process;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.AssetManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;

/**
 * TODO:
 * - quicksuite: use status to get in a single command both the games and messages
 * - support new msgs in forums
 * - don't download the sgf at every move, but rather cache the sgf and only use the last move given by status (what about if a comment is made on the last move ?)
 * - better graphics / pictures
 * - init goban zoom from physical screen size
 * 
 * @author xtof
 *
 */
public class GoJsActivity extends FragmentActivity {
  public static final String dgappversion = "1.8";
  
  private long rx=0, tx=0, rx0=-7, tx0=-7;
  private int uid=-1;
  private Handler mHandler = new Handler();
  private boolean quitall = false;
  private final Runnable mRunnable = new Runnable() {
    public void run() {
      updateTraffic();
      if (!quitall) mHandler.postDelayed(mRunnable, 3000);
    }
  };

  ServerConnection server=null;
  AndroidServerConnection androidServer = null;
  int chosenServer=0, chosenLogin=0;

  //    String server;
  enum guistate {nogame, play, markDeadStones, checkScore, message, review, forums};
  guistate curstate = guistate.nogame;

  File eidogodir;
  final boolean forcecopy=false;
  WebView wv;
  ArrayList<Game> games2play = new ArrayList<Game>();
  int curgidx2play=0,moveid=0;
  final String netErrMsg = "Connection errors or timeout, you may retry";
  static GoJsActivity main;
    private int numEventsReceived = 0;

  //  private static void copyFile(InputStream in, OutputStream out) throws IOException {
  //    byte[] buffer = new byte[1024];
  //    int read;
  //    while((read = in.read(buffer)) != -1){
  //      out.write(buffer, 0, read);
  //    }
  //  }

  private void setButtons(final String b1, final String b2, final String b3, final String b4, final String b5) {
    setButtons(b1, b2, b3, b4);
    this.runOnUiThread(new Runnable() {
      @Override
      public void run() {
        Button but5 = (Button)findViewById(R.id.but5);
        but5.setText(b5);
      }
    });
  }
  private void setButtons(final String b1, final String b2, final String b3, final String b4) {
    this.runOnUiThread(new Runnable() {
      @Override
      public void run() {
        Button but1 = (Button)findViewById(R.id.but1);
        but1.setText(b1);
        Button but2 = (Button)findViewById(R.id.but2);
        but2.setText(b2);
        Button but3 = (Button)findViewById(R.id.but3);
        but3.setText(b3);
        Button but4 = (Button)findViewById(R.id.but4);
        but4.setText(b4);
      }
    });
  }
  private guistate lastGameState;
  void changeState(guistate newstate) {
    if (curstate==guistate.review && newstate!=guistate.review)
      GoJsActivity.main.wv.loadUrl("javascript:eidogo.autoPlayers[0].detMoveNumber()");
    if (curstate==guistate.markDeadStones && newstate!=guistate.markDeadStones)
      wv.loadUrl("javascript:eidogo.autoPlayers[0].detmarkp()");
    System.out.println("inchangestate "+curstate+" .. "+newstate);
    switch (newstate) {
    case nogame:
      // we allow clicking just in case the user wants to play locally, disconnected
      writeInLabel("Getgame: download game from DGS");
      wv.loadUrl("javascript:eidogo.autoPlayers[0].detallowClicking()");
      setButtons("Games","Zm+","Zm-","Msg"); break;
    case play:
      writeInLabel("click on the board to play");
      wv.loadUrl("javascript:eidogo.autoPlayers[0].detallowClicking()");
      setButtons("Send","Zm+","Zm-","Reset","Bck"); break;
    case markDeadStones:
      writeInLabel("click on the board to mark dead stones");
      wv.loadUrl("javascript:eidogo.autoPlayers[0].detallowClicking()");
      showMessage("Scoring phase: put one X marker on each dead group and click SCORE to check score (you can still change after)");
      // just in case the board is already rendered...
      // normally, detmarkx() is called right after the board is displayed,
      // but here, the board is displayed long ago, so we have to call it manually
      wv.loadUrl("javascript:eidogo.autoPlayers[0].detmarkx()");
      setButtons("Score","Zm+","Zm-","Play"); break;
    case checkScore: 
      wv.loadUrl("javascript:eidogo.autoPlayers[0].detforbidClicking()");
      setButtons("Accept","Zm+","Zm-","Refuse"); break;
    case message:
      wv.loadUrl("javascript:eidogo.autoPlayers[0].detforbidClicking()");
      lastGameState=curstate;
      setButtons("GetMsg","Invite","SendMsg","Back2game"); break;
    case review:
      setButtons("LastCmt","Zm+","Zm-","ListG","Fwd");break;
    default:
    }
    curstate=newstate;
  }

  public String showCounting(JSONObject o) {
    String sc="";
    try {
      sc = o.getString("score");
      String bt = o.getString("black_territory").trim();
      for (int i=0;i<bt.length();i+=2) {
        String coords = bt.substring(i, i+2);
        wv.loadUrl("javascript:eidogo.autoPlayers[0].cursor.node.pushProperty(\"TB\",\""+coords+"\")");
      }
      bt = o.getString("white_dead").trim();
      for (int i=0;i<bt.length();i+=2) {
        String coords = bt.substring(i, i+2);
        wv.loadUrl("javascript:eidogo.autoPlayers[0].cursor.node.pushProperty(\"TB\",\""+coords+"\")");
      }
      String wt = o.getString("white_territory").trim();
      for (int i=0;i<wt.length();i+=2) {
        String coords = wt.substring(i, i+2);
        wv.loadUrl("javascript:eidogo.autoPlayers[0].cursor.node.pushProperty(\"TW\",\""+coords+"\")");
      }
      wt = o.getString("black_dead").trim();
      for (int i=0;i<wt.length();i+=2) {
        String coords = wt.substring(i, i+2);
        wv.loadUrl("javascript:eidogo.autoPlayers[0].cursor.node.pushProperty(\"TW\",\""+coords+"\")");
      }

      wv.loadUrl("javascript:eidogo.autoPlayers[0].refresh()");
    } catch (JSONException e) {
      e.printStackTrace();
      showMessage("warning: error counting");
    }
    return sc;
  }

  /**
   * we remove all territories and X in the goban but not in the sgf,
   * because we'll need them to compute the "toggled dead stones" to estimate the score
   * we then add back the X from the server onto the goban, so that the user knows which stones were
   * marked dead and he can modify them. It should also make the toggle computing easier
   */
  void cleanTerritory() {
    wv.loadUrl("javascript:eidogo.autoPlayers[0].detsoncleanT()");
    Game g = Game.gameShown;
    String serverMarkedStones = g.deadstInSgf;
    System.out.println("clean territory: serverMarkedStones: "+serverMarkedStones);
    for (int i=0;i<serverMarkedStones.length();i+=2) {
      String coord = serverMarkedStones.substring(i,i+2);
      wv.loadUrl("javascript:eidogo.autoPlayers[0].cursor.node.pushProperty(\"MA\", \""+coord+"\")");
    }
    wv.loadUrl("javascript:eidogo.autoPlayers[0].refresh()");
  }

  void copyEidogo(final String edir, final File odir) {
      EventManager.getEventManager().sendEvent(eventType.copyEidogoStart);
    AssetManager mgr = getResources().getAssets();
    try {
      String[] fs = mgr.list(edir);
      for (String s : fs) {
        try {
          InputStream i = mgr.open(edir+"/"+s);
          // this is a file
          File f0 = new File(odir,s);
          FileOutputStream f = new FileOutputStream(f0);
          for (;;) {
            int d = i.read();
            if (d<0) break;
            f.write(d);
          }
          f.close();
          i.close();
        } catch (FileNotFoundException e) {
          // this is a directory and not a file
          File f = new File(odir,s);
          f.mkdirs();
          copyEidogo(edir+"/"+s,f);
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
      showMessage("DISK ERROR: "+e.toString());
    }
    System.out.println("endof copy");
    EventManager.getEventManager().sendEvent(eventType.copyEidogoEnd);
  }
  
  /*
   * lifecycle:
   * onCreate() ... onDestroy()
   * visible:
   * onStart() ... onStop() : can be called multiple times
   * in front of all others:
   * onResume() ... onPause() : interacting with user; called frequently
   */
  
  @Override
  public void onDestroy() {
    super.onDestroy();
    quitall=true;
    if (server!=null) server.closeConnection();
    if (androidServer!=null) androidServer.closeConnection();
  }
  
  @Override
  public void onRestart() {
    super.onRestart();
    loadSgf();
  }
  
  public void updateTraffic() {
    long newrx = TrafficStats.getTotalRxBytes();
    long newtx = TrafficStats.getTotalTxBytes();
    if (rx!=newrx||tx!=newtx) {
      rx=newrx; tx=newtx;
      writeTraffix(rx+tx);
    }
  }
  
  private void writeTraffix(final long nbytes) {
    runOnUiThread(new Runnable() {
      @Override
      public void run() {
        final TextView label = (TextView)findViewById(R.id.textView1);
        if (label!=null) {
          CharSequence a = label.getText();
          if (a==null) a="";
          String s = a.toString();
          if (s.endsWith("kB")) {
            int i=s.lastIndexOf(' ');
            s=s.substring(0, i);
          }
          int kb = (int)((nbytes - rx0 - tx0) / (long)1024);
          label.setText(s+" "+kb+"kB");
          label.invalidate();
        }
      }
    });
  }
  
  public void writeInLabel(final String s) {
    runOnUiThread(new Runnable() {
      @Override
      public void run() {
        final TextView label = (TextView)findViewById(R.id.textView1);
        label.setText(s);
        label.invalidate();
      }
    });
  }

  void initFinished() {
    System.out.println("init finished");
    writeInLabel("init done. You can play !");
    final Button button1 = (Button)findViewById(R.id.but1);
    button1.setClickable(true);
    button1.setEnabled(true);
    final Button button2 = (Button)findViewById(R.id.but2);
    button2.setClickable(true);
    button2.setEnabled(true);
    final Button button3 = (Button)findViewById(R.id.but3);
    button3.setClickable(true);
    button3.setEnabled(true);
    button1.invalidate();
    button2.invalidate();
    button3.invalidate();
  }

  private String getMarkedStones(String sgf) {
    String res = "";
    int i=0;
    for (;;) {
      System.out.println("debug "+sgf.substring(i));
      int j=sgf.indexOf("MA[",i);
      if (j<0) {
        return res;
      } else {
        i=j+2;
        while (i<sgf.length()) {
          if (sgf.charAt(i)!='[') break;
          j=sgf.indexOf(']',i);
          if (j<0) break;
          String stone = sgf.substring(i+1,j);
          res+=stone;
          i=j+1;
        }
      }
    }
  }
  
  private class myWebViewClient extends WebViewClient {
    @Override
    public void onPageFinished(final WebView view, String url) {
        System.out.println("page finished loading");
      if (curstate!=guistate.review)
        view.loadUrl("javascript:eidogo.autoPlayers[0].last()");
      else if (!Reviews.isNotReviewStage) {
          Reviews.advance();
      }
      if (curstate==guistate.markDeadStones)
        view.loadUrl("javascript:eidogo.autoPlayers[0].detmarkx()");
      final EventManager em = EventManager.getEventManager();
      em.sendEvent(eventType.gobanReady);
      
      // ask for comments to display them in big
      System.out.println("page finished call detComments");
      view.loadUrl("javascript:eidogo.autoPlayers[0].detComments()");
    }
    
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
      System.out.println("mywebclient detecting command from javascript: "+url);
      int i=url.indexOf("androidcall01");
      if (i>=0) {
        if (url.substring(i).startsWith("androidcall01|C|")) {
            System.out.println("comment command initreview "+Reviews.isNotReviewStage);
          if (!Reviews.isNotReviewStage) return true;
          Reviews.setComment(url.substring(i+16));
          if (Reviews.comment.length()>0) longToast(Reviews.comment, 5);
          return true;
        }
        if (url.substring(i).startsWith("androidcall01|M|")) {
          // this is triggered when the player gets out of review mode
          Integer mn = Integer.parseInt(url.substring(i+16));
          Reviews.curmove=mn;
          Reviews.saveCurReview();
          return true;
        }
        int j=url.lastIndexOf('|')+1;
        String lastMove = url.substring(j);

        // this is trigerred when the user clicks the SEND button or by the sgf downloader when detecting a SCORE2 phase
        final Game g = Game.gameShown;
        if (curstate==guistate.markDeadStones) {
          String sgfdata = url.substring(i+14, j);
          String deadstones=getMarkedStones(sgfdata);
          final EventManager em = EventManager.getEventManager();
          EventManager.EventListener f = new EventManager.EventListener() {
            @Override
            public String getName() {return "mywebclient";}
            @Override
            public synchronized void reactToEvent() {
              em.unregisterListener(eventType.moveSentEnd, this);
              JSONObject o = server.o;
              if (o==null) {
                  // error: do nothing
                  return;
              }
              String err;
              try {
                  err = o.getString("error");
                  if (err!=null&&err.length()>0) {
                      // error: do nothing
                      return;
                  }
              } catch (JSONException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              // show territories
              String sc = showCounting(o);
              showMessage("dead stones sent; score="+sc);
              writeInLabel("score: "+sc);
              changeState(guistate.checkScore);
            }
          };
          em.registerListener(eventType.moveSentEnd, f);
          g.sendDeadstonesToServer(deadstones, server, true);
        } else {
          final EventManager em = EventManager.getEventManager();
          EventManager.EventListener f = new EventManager.EventListener() {
            @Override
            public String getName() {return "mywebclient";}
            @Override
            public synchronized void reactToEvent() {
              em.unregisterListener(eventType.moveSentEnd, this);
              JSONObject o = server.o;
              if (o==null) {
                  // error: don't switch game
                  return;
              }
              String err;
              try {
                  err = o.getString("error");
                  if (err!=null&&err.length()>0) {
                      // error: don't switch game
                      return;
                  }
              } catch (JSONException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              // switch to next game
              g.finishedWithThisGame();
              if (Game.getGames().size()==0) {
                showMessage("No more games locally");
                changeState(guistate.nogame);
              } else
                downloadAndShowGame();
            }
          };
          em.registerListener(eventType.moveSentEnd, f);
          g.sendMove2server(lastMove,server);
        }
        return true;
      } else {
        // its not an android call back 
        // let the browser navigate normally
        return false;
      }
    }   
  }  

  void showGame(final Game g) {
    if (g.getGameStatus().startsWith("SCORE")) {
        System.out.println("scoring phase detected in showgame");
      // TODO: I tried, but it's really difficult to handle correctly the scoring phase;
      // so for now, I just call the browser to resolve this stage !
      //            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(server.getUrl()+"game.php?gid="+g.getGameID()));
      //            startActivity(browserIntent);

      EventManager.getEventManager().registerListener(eventType.gobanReady, new EventManager.EventListener() {
        @Override
        public void reactToEvent() {
          EventManager.getEventManager().unregisterListener(eventType.gobanReady, this);
          wv.loadUrl(server.getUrl()+"game.php?gid="+g.getGameID());
        }
        @Override
        public String getName() {
          return "SCORE_phase";
        }
      });
      changeState(guistate.nogame);
      wv.loadUrl(server.getUrl()+"login.php?userid="+server.getLogin()+"&passwd="+server.getPwd());

      //            skipGame();
      return;
    }

    g.showGame();
    // detect if the other player has already agreed on dead stones
    //        if (g.getGameStatus().equals("SCORE2")) {
    //            System.out.println("Check score phase detected !");
    //            final EventManager em = EventManager.getEventManager();
    //            // this listener is trigerred when the goban has finished displayed
    //            final EventManager.EventListener drawTerritory = new EventManager.EventListener() {
    //                @Override
    //                public void reactToEvent() {
    //                    em.unregisterListener(eventType.gobanReady, this);
    //                    try {
    //            Thread.sleep(4000);
    //          } catch (InterruptedException e) {
    //            e.printStackTrace();
    //          }
    //                    JSONObject o = server.o;
    //                    if (o==null) {
    //                        // error: do nothing
    //                        return;
    //                    }
    //                    String err = o.getString("error");
    //                    if (err!=null&&err.length()>0) {
    //                        // error: do nothing
    //                        return;
    //                    }
    //                    // show territories
    //                    String sc = showCounting(o);
    //                    showMessage("dead stones sent; score="+sc);
    //                    writeInLabel("score: "+sc);
    //                    changeState(guistate.checkScore);
    //                }
    //                @Override
    //                public String getName() {return "drawTerritory";}
    //            };
    //            em.registerListener(eventType.moveSentEnd, new EventManager.EventListener() {
    //              // this listener is triggered when the server sends back the score and dead stones
    //                @Override
    //                public void reactToEvent() {
    //                    em.unregisterListener(eventType.moveSentEnd, this);
    //                    curstate=guistate.markDeadStones;
    //                    // show the board game
    //                    String f=eidogodir+"/example.html";
    //                    System.out.println("debugloadurl file://"+f);
    //                    em.registerListener(eventType.gobanReady, drawTerritory);
    //                    // we then ask the goban to show the game in lark deadstone mode, but the second listener
    //                    // will be immediately trigerred once the goban is shown
    //                    wv.loadUrl("file://"+f);
    //                }
    //                @Override
    //                public String getName() {return "showgamedeadstones";}
    //            });
    //            // send NO stones to server to get the final score
    //            g.sendDeadstonesToServer("", server, false);
    //        } else {
    //            // detect if in scoring phase
    //            // TODO: replace this by checking the game STATUS !
    //            if (g.isTwoPasses()) {
    //                System.out.println("scoring phase detected !");
    //                changeState(guistate.markDeadStones);
    //            }
    //        }

    // show the board game
    String f=eidogodir+"/example.html";
    System.out.println("debugloadurl file://"+f);
    System.out.println("just before loading the URL: ");
    wv.loadUrl("file://"+f);
  }

  void downloadAndShowGame() {
    int ngames = Game.getGames().size();
    if (curgidx2play>=ngames) {
      if (ngames==0) {
        showMessage("No game to show");
        return;
      } else {

        curgidx2play=0;
      }
    }
    System.out.println("showing game "+curgidx2play);

    final Game g = Game.getGames().get(curgidx2play);
    g.downloadGame(server);
    final EventManager em = EventManager.getEventManager();
    em.registerListener(eventType.GameOK, new EventManager.EventListener() {
      @Override
      public String getName() {return "downloadAndShowGame";}
      @Override
      public synchronized void reactToEvent() {
        em.unregisterListener(eventType.GameOK, this);
        showGame(g);
      }
    });
  }

  // warning; this requires API 5 (> v2.0)
  @Override
  public void onBackPressed() {
    System.out.println("back pressed");
    if (curstate==guistate.nogame) {
      super.onBackPressed();
    } else if (curstate==guistate.forums) {
      if (Forums.back()) GUI.getGUI().showHome();
    } else
      GUI.getGUI().showHome();
  }
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initGUI();
  }
  void initGUI() {
    // ====================================
    setContentView(R.layout.activity_main);

    wv = (WebView)findViewById(R.id.web1);

    wv.setWebViewClient(new myWebViewClient());
    wv.getSettings().setJavaScriptEnabled(true);
    wv.getSettings().setSupportZoom(true);
    //    String myHTML  = "<html><body><a href='androidcall01|123456'>Call Back to Android 01 with param 123456</a>my Content<p>my Content<p>my Content<p><a href='androidcall02|7890123'>Call Back to Android 01 with param 7890123</a></body></html>";
    //    wv.loadDataWithBaseURL("about:blank", myHTML, "text/html", "utf-8", "");
    //    wv.addJavascriptInterface(new WebAppInterface(this), "Android");

    {
      final Button button = (Button)findViewById(R.id.morebutts);
      button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          System.out.println("press last button on state "+curstate);
          showMoreButtons();
        }
      });
    }
    {
      final Button button = (Button)findViewById(R.id.but1);
      button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
          System.out.println("press button1 on state "+curstate);
          switch(curstate) {
          case nogame: // download games
            downloadListOfGames();
            break;
          case play: // send the move
            // ask eidogo to send last move; it will be captured by the web listener
            wv.loadUrl("javascript:eidogo.autoPlayers[0].detsonSend()");
            break;
          case markDeadStones: // send a request to the server to compute the score
            // ask eidogo to give sgf, which shall contain X
            wv.loadUrl("javascript:eidogo.autoPlayers[0].detsonSend()");
            break;
          case checkScore: // accept the current score evaluation
            acceptScore();
            break;
          case message: // get messages
            if (!initServer()) return;
            Message.downloadMessages(server,main);
            break;
                    case review: // reprint comment
                        longToast(Reviews.comment, 5);
                        break;
          }

          //                {
          //                    Intent intent = new Intent(Intent.ACTION_VIEW);
          //                    intent.addCategory(Intent.CATEGORY_BROWSABLE);
          //                    intent.setDataAndType(Uri.fromFile(ff), "application/x-webarchive-xml");
          //                    //                  intent.setDataAndType(Uri.fromFile(ff), "text/html");
          //                    intent.setClassName("com.android.browser", "com.android.browser.BrowserActivity");
          //                    //                  intent.setClassName("Lnu.tommie.inbrowser", "com.android.browser.BrowserActivity");
          //                    startActivity(intent);
          //                    // to launch a browser:
          //                    //                  Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("file:///mnt/sdcard/"));
          //                }
        }
      });
    }
    {
      final Button button = (Button)findViewById(R.id.but2);
      button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          System.out.println("press button2 on state "+curstate);
          switch(curstate) {
          case nogame:
          case play:
          case markDeadStones:
                    case checkScore:
                    case review:
            wv.zoomIn();
            wv.invalidate();
            break;
          case message: // send invitation
            System.out.println("send invitation");
                        if (!initServer()) return;
            Message.invite(server, main);
            break;
          }
        }
      });
    }
    {
      final Button button = (Button)findViewById(R.id.but3);
      button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          System.out.println("press button3 on state "+curstate);
          switch(curstate) {
          case nogame:
          case play:
          case markDeadStones:
                    case review:
          case checkScore:
            wv.zoomOut();
            wv.invalidate();
            break;
          case message: // send message
            if (!initServer()) {
              showMessage("Connection problem");
            } else
              Message.send(server,main);
            break;
          }
        }
      });
    }
        {
            final Button button = (Button)findViewById(R.id.but4);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    System.out.println("press button4 on state "+curstate);
                    switch(curstate) {
                    case nogame: // send message
                        changeState(guistate.message); break;
                    case play: // reset to the original download SGF
                        showGame(Game.gameShown);
                        break;
                    case markDeadStones: // cancels marking stones and comes back to playing
                        changeState(guistate.play);
                        break;
                    case checkScore: // refuse score and continues to mark stones
                        refuseScore();
                        break;
                    case message: // go back to last game mode
                        changeState(lastGameState);
                        break;
                    case review:
                        Reviews.showList();
                        break;
                    }
                }
            });
        }
        {
            final Button button = (Button)findViewById(R.id.but5);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    System.out.println("press button5 on state "+curstate);
                    CharSequence t = button.getText();
                    if (t.equals("Fwd"))
                      wv.loadUrl("javascript:eidogo.autoPlayers[0].fwd()");
                    else if (t.equals("Bck"))
                      wv.loadUrl("javascript:eidogo.autoPlayers[0].backward()");
                    else Log.w("button5", "unknow text "+t);
                }
            });
        }

    // ====================================
    // copy the eidogo dir into the external sdcard
    // only copy if it does not exist already
    // this takes time, so do it in a thread and show a message for the user to wait
    boolean mExternalStorageAvailable = false;
    boolean mExternalStorageWriteable = false;
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
      mExternalStorageAvailable = mExternalStorageWriteable = true;
    } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
      mExternalStorageAvailable = true;
      mExternalStorageWriteable = false;
    } else {
      mExternalStorageAvailable = mExternalStorageWriteable = false;
    }
    if (mExternalStorageAvailable&&mExternalStorageWriteable) {
      File d = getExternalCacheDir();
      eidogodir = new File(d, "eidogo");
      if (forcecopy||!eidogodir.exists()) {
        eidogodir.mkdirs();
        final Button button3 = (Button)findViewById(R.id.but3);
        button3.setClickable(false);
        button3.setEnabled(false);
        final Button button2= (Button)findViewById(R.id.but2);
        button2.setClickable(false);
        button2.setEnabled(false);
        final Button button1= (Button)findViewById(R.id.but1);
        button1.setClickable(false);
        button1.setEnabled(false);
        button1.invalidate();
        button2.invalidate();
        button3.invalidate();
        new CopyEidogoTask().execute("noparms");
      } else {
        showMessage("eidogo already on disk");
        initFinished();
      }
    } else {
      showMessage("R/W ERROR sdcard");
    }


    // manage events to show/hide the waiting dialog
    main = this;

    final EventManager em = EventManager.getEventManager();
    EventManager.EventListener waitDialogShower = new EventManager.EventListener() {
      @Override
      public String getName() {return "onStartShowWaitDialog";}
      @Override
      public synchronized void reactToEvent() {
          GUI.showWaitingWin();
        numEventsReceived++;
      }
    };
    // we put here all events that should trigger the "waiting" dialog
    em.registerListener(eventType.downloadGameStarted, waitDialogShower);
    em.registerListener(eventType.downloadListStarted, waitDialogShower);
    em.registerListener(eventType.loginStarted, waitDialogShower);
    em.registerListener(eventType.moveSentStart, waitDialogShower);
        em.registerListener(eventType.ladderStart, waitDialogShower);
        em.registerListener(eventType.ladderChallengeStart, waitDialogShower);
        em.registerListener(eventType.copyEidogoStart, waitDialogShower);

    EventManager.EventListener waitDialogHider = new EventManager.EventListener() {
      @Override
      public String getName() {return "onStartHideWaitDialog";}
      @Override
      public synchronized void reactToEvent() {
        try {
          --numEventsReceived;
          if (numEventsReceived<0) {
            System.out.println("ERROR events stream...");
            return;
          }
          if (numEventsReceived==0) {
              GUI.hideWaitingWin();
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    };
    em.registerListener(eventType.downloadGameEnd, waitDialogHider);
    em.registerListener(eventType.downloadListEnd, waitDialogHider);
    em.registerListener(eventType.loginEnd, waitDialogHider);
    em.registerListener(eventType.moveSentEnd, waitDialogHider);
    em.registerListener(eventType.ladderEnd, waitDialogHider);
        em.registerListener(eventType.ladderChallengeEnd, waitDialogHider);
        em.registerListener(eventType.copyEidogoEnd, waitDialogHider);

        // to show message
        em.registerListener(eventType.showMessage, new EventManager.EventListener() {
            @Override
            public void reactToEvent() {
                showMessage(EventManager.getEventManager().message);
            }
            @Override
            public String getName() {return "showMessage";}
        });
        
    // initialize guistate
    changeState(guistate.nogame);
    
    // initialize traffic stats
    ActivityManager mgr = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
    // strange: the initial bandwidth of this uid is not 0 ?!
    uid = Process.myUid();
    rx=TrafficStats.getTotalRxBytes();
    tx=TrafficStats.getTotalTxBytes();
    if (rx0==-7) {
      rx0=rx; tx0=tx;
    }
    if (rx == TrafficStats.UNSUPPORTED || tx == TrafficStats.UNSUPPORTED) {
      AlertDialog.Builder alert = new AlertDialog.Builder(this);
      alert.setTitle("Uh Oh!");
      alert.setMessage("Your device does not support traffic stat monitoring.");
      alert.show();
    } else {
      mHandler.postDelayed(mRunnable, 3000);
    }
    writeTraffix(rx+tx);
  }

  private void acceptScore() {
    final Game g = Game.gameShown;
    final EventManager em = EventManager.getEventManager();
    EventManager.EventListener f = new EventManager.EventListener() {
      @Override
      public String getName() {return "acceptScore";}
      @Override
      public synchronized void reactToEvent() {
        em.unregisterListener(eventType.moveSentEnd, this);
        JSONObject o = server.o;
        if (o==null) {
            // error: don't switch game
            return;
        }
        String err;
        try {
            err = o.getString("error");
            if (err!=null&&err.length()>0) {
                // error: don't switch game
                return;
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // switch to next game
        g.finishedWithThisGame();
        if (Game.getGames().size()==0) {
            showMessage("No more games locally");
            changeState(guistate.nogame);
        } else
          downloadAndShowGame();
      }
    };
    em.registerListener(eventType.moveSentEnd, f);
    g.acceptScore(server);
  }
  private void refuseScore() {
    cleanTerritory();
    changeState(guistate.markDeadStones);
  }

  public static class ErrDialogFragment extends DialogFragment {
    String cmdSentBeforeNetErr;
    eventType eventTobesent;
    GoJsActivity main;
    public void setArguments(String s, eventType e, GoJsActivity m) {
      cmdSentBeforeNetErr = s;
      eventTobesent = e;
      main=m;
    }
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
      final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
      // Get the layout inflater
      LayoutInflater inflater = getActivity().getLayoutInflater();

      // Inflate and set the layout for the dialog
      // Pass null as the parent view because its going in the dialog layout
      builder.setView(inflater.inflate(R.layout.error, null))
      // Add action buttons
      .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
          EventManager.getEventManager().sendEvent(eventTobesent);
          // TODO: maybe the action reacting to the eventTobesent will change the state after the following state...
          Thread.yield();
          switch (main.curstate) {
          default: main.changeState(guistate.nogame);
          }
          main.changeState(guistate.nogame);
          ErrDialogFragment.this.getDialog().cancel();
        }
      })
      .setPositiveButton("Retry", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
          main.server.sendCmdToServer(cmdSentBeforeNetErr, null, eventTobesent);
          ErrDialogFragment.this.getDialog().cancel();
        }
      });
      return builder.create();
    }
  }
  private ErrDialogFragment errdialog = null;

  private boolean initServer() {
    System.out.println("call initserver "+server);
    if (server!=null) return true;
    String loginkey = PrefUtils.PREFS_LOGIN_USERNAME_KEY;
    String pwdkey = PrefUtils.PREFS_LOGIN_PASSWORD_KEY;
    if (chosenLogin==1) {
      loginkey = PrefUtils.PREFS_LOGIN_USERNAME2_KEY;
      pwdkey = PrefUtils.PREFS_LOGIN_PASSWORD2_KEY;
    }
    String u = PrefUtils.getFromPrefs(this, loginkey ,null);
    String p = PrefUtils.getFromPrefs(this, pwdkey ,null);
    System.out.println("credsdebug "+u+" "+p+" "+chosenLogin);
    if (u==null||p==null) {
      showMessage("Please enter your credentials first via menu Settings");
      return false;
    }

    final GoJsActivity m = this;
    System.out.println("credentials passed to server "+u+" "+p);
    if (server==null) {
      server = new ServerConnection(chosenServer, u, p);
      DetLogger l = new DetLogger() {
        @Override
        public void showMsg(String s) {
          if (s.startsWith("Net error|")) {
            int i=s.lastIndexOf('|');
            String cmdSentBeforeNetErr = s.substring(10, i);
            eventType eventTobesent = eventType.valueOf(s.substring(i+1));
            errdialog = new ErrDialogFragment();
            errdialog.setArguments(cmdSentBeforeNetErr, eventTobesent, m);
            errdialog.show(getSupportFragmentManager(),"Net_error");
          } else 
            showMessage(s);
        }
      };
      server.setLogger(l);
    }
    return true;
  }
  boolean initAndroidServer() {
    if (androidServer!=null) return true;
    String loginkey = PrefUtils.PREFS_LOGIN_USERNAME_KEY;
    String pwdkey = PrefUtils.PREFS_LOGIN_PASSWORD_KEY;
    if (chosenLogin==1) {
      loginkey = PrefUtils.PREFS_LOGIN_USERNAME2_KEY;
      pwdkey = PrefUtils.PREFS_LOGIN_PASSWORD2_KEY;
    }
    String u = PrefUtils.getFromPrefs(this, loginkey ,null);
    String p = PrefUtils.getFromPrefs(this, pwdkey ,null);
    System.out.println("credsdebug "+u+" "+p+" "+chosenLogin);
    if (u==null||p==null) {
      showMessage("Please enter your credentials first via menu Settings");
      return false;
    }
    System.out.println("credentials passed to server "+u+" "+p);
    if (androidServer==null) {
      androidServer = new AndroidServerConnection(chosenServer, u, p);
    }
    return true;
  }

  private void downloadListOfGames() {
    if (!initServer()) return;
    final EventManager em = EventManager.getEventManager();
    EventManager.EventListener l = new EventManager.EventListener() {
      @Override
      public String getName() {return "downloadListOfGames";}
      @Override
      public void reactToEvent() {
        em.unregisterListener(eventType.downloadListGamesEnd, this);
        int ngames = Game.getGames().size();
        System.out.println("in downloadList listener "+ngames);
        if (ngames>=0)
          showMessage("Nb games to play: "+ngames);
        if (ngames>0) {
          curgidx2play=0;
          downloadAndShowGame();
          // download detects if 2 passes and auto change state to markdeadstones
          if (curstate!=guistate.markDeadStones) changeState(guistate.play);
        } else return;
      }
    };
    em.registerListener(eventType.downloadListGamesEnd, l);
    Game.loadStatusGames(server);
  }

  private class CopyEidogoTask extends AsyncTask<String, Void, String> {
    protected String doInBackground(String... parms) {
      copyEidogo("eidogo",eidogodir);
      return "init done";
    }
    protected void onPostExecute(String res) {
      System.out.println("eidogo copy finished");
      initFinished();
    }
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.action_settings:
        if (curstate==guistate.forums && Forums.inList>0) {
            Forums.switchShowNew();
        } else
            ask4credentials();
      return true;
    default:
      return super.onOptionsItemSelected(item);
    }
  }

  void showMessage(final String txt) {
    this.runOnUiThread(new Runnable() {
      @Override
      public void run() {
        Toast.makeText(getBaseContext(), txt, Toast.LENGTH_LONG).show();
      }
    });
  }

  private void ask4credentials() {
    System.out.println("calling settings");
    final Context c = this;
    class LoginDialogFragment extends DialogFragment {
      @Override
      public Dialog onCreateDialog(Bundle savedInstanceState) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        // Get the layout inflater
        LayoutInflater inflater = getActivity().getLayoutInflater();

        // Inflate and set the layout for the dialog
        // Pass null as the parent view because its going in the dialog layout
        builder.setView(inflater.inflate(R.layout.dialog_signin, null))
        // Add action buttons
        .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int id) {
            // sign in the user ...
            TextView username = (TextView)LoginDialogFragment.this.getDialog().findViewById(R.id.username);
            TextView pwd = (TextView)LoginDialogFragment.this.getDialog().findViewById(R.id.password);
            String userkey = PrefUtils.PREFS_LOGIN_USERNAME_KEY;
            String pwdkey  = PrefUtils.PREFS_LOGIN_PASSWORD_KEY;
            if (chosenLogin==1) {
              System.out.println("saving creds 1");
              userkey = PrefUtils.PREFS_LOGIN_USERNAME2_KEY;
              pwdkey  = PrefUtils.PREFS_LOGIN_PASSWORD2_KEY;
            } else
              System.out.println("saving creds 0");
            PrefUtils.saveToPrefs(c, userkey, username.getText().toString());
            PrefUtils.saveToPrefs(c, pwdkey, (String)pwd.getText().toString());
            showMessage("Credentials saved");
          }
        })
        .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            LoginDialogFragment.this.getDialog().cancel();
          }
        });
        return builder.create();
      }
    }
    LoginDialogFragment dialog = new LoginDialogFragment();
    dialog.show(getSupportFragmentManager(),"dgs signin");
  }

  private void skipGame() {
    if (Game.getGames().size()<=1) {
      showMessage("No more games downloaded; retry GetGames ?");
      changeState(guistate.nogame);
      return;
    }
    if (++curgidx2play>=Game.getGames().size()) curgidx2play=0;
    downloadAndShowGame();
  }
  // TODO: move this method into Game !
  private void resignGame() {
    String cmd = "quick_do.php?obj=game&cmd=resign&gid="+Game.gameShown.getGameID()+"&move_id="+Game.gameShown.moveid;
    if (Game.gameShown.getMessage()!=null)
        cmd+="&msg="+URLEncoder.encode(Game.gameShown.getMessage().toString());
    EventManager.getEventManager().registerListener(eventType.moveSentEnd, new EventManager.EventListener() {
      @Override
      public void reactToEvent() {
        EventManager.getEventManager().unregisterListener(eventType.moveSentEnd,this);
        // switch to next game
        Game.gameShown.finishedWithThisGame();
        if (Game.getGames().size()==0) {
          showMessage("No more games locally");
          changeState(guistate.nogame);
        } else
          downloadAndShowGame();
      }
      @Override
      public String getName() {return "resign";}
    });
    server.sendCmdToServer(cmd, eventType.moveSentStart, eventType.moveSentEnd);
  }

  private void loadSgf() {
    System.out.println("eidogodir: "+eidogodir);
    String f=eidogodir+"/example.html";
    wv.loadUrl("file://"+f);
  }

  private void addGameMessage() {
    if (Game.gameShown==null) {
      showMessage("you have no game to attach a message to");
      return;
    }
    class GameMessageDialogFragment extends DialogFragment {
      GoJsActivity main;
      public void setArguments(GoJsActivity m) {
        main=m;
      }
      @Override
      public Dialog onCreateDialog(Bundle savedInstanceState) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        // Get the layout inflater
        LayoutInflater inflater = getActivity().getLayoutInflater();

        // Inflate and set the layout for the dialog
        // Pass null as the parent view because its going in the dialog layout
        final View v = inflater.inflate(R.layout.gamemsg, null);
        builder.setView(v)
        // Add action buttons
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            GameMessageDialogFragment.this.getDialog().cancel();
          }
        })
        .setPositiveButton("Add message", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            RadioButton r = (RadioButton)v.findViewById(R.id.introMsg);
            if (r.isChecked()) {
              CharSequence msg = r.getText();
              Game.gameShown.setMessage(msg);
            } else {
              r = (RadioButton)v.findViewById(R.id.endMsg);
              if (r.isChecked()) {
                CharSequence msg = r.getText();
                Game.gameShown.setMessage(msg);
              } else {
                r = (RadioButton)v.findViewById(R.id.otherMsg);
                if (r.isChecked()) {
                  EditText tt = (EditText)v.findViewById(R.id.textOtherMsg);
                  CharSequence msg = tt.getText();
                  if (msg.toString().trim().length()==0)
                    Game.gameShown.setMessage(null);
                  else
                    Game.gameShown.setMessage(msg);
                } else {
                  System.out.println("gamemsg nothing selected !!");
                } 
              }
            }
            GameMessageDialogFragment.this.getDialog().cancel();
          }
        });
        if (Game.gameShown.getMessage()!=null) {
          RadioButton r = (RadioButton)v.findViewById(R.id.otherMsg);
          r.setSelected(true);
          TextView msg = (TextView)v.findViewById(R.id.textOtherMsg);
          msg.setText(Game.gameShown.getMessage());
        }
        return builder.create();
      }
    }
    GameMessageDialogFragment gameMsgDialog = new GameMessageDialogFragment();
    gameMsgDialog.setArguments(this);
    gameMsgDialog.show(getSupportFragmentManager(),"game messages");
  }

  private void viewLadder(final int ladid) {
        if (!initAndroidServer()) return;
        androidServer.ladd=new Ladder(ladid);
        EventManager.getEventManager().registerListener(eventType.ladderEnd, new EventManager.EventListener() {
      @Override
      public void reactToEvent() {
        EventManager.getEventManager().unregisterListener(eventType.ladderEnd,this);
        if (androidServer.ladd==null||androidServer.ladd.getCachedLadder()==null||androidServer.ladd.getCachedLadder().length==0) {
          showMessage("Problem: are your registered in the ladder ? can you still challenge ?");
              return;
        }
            class DetListDialogFragment extends DialogFragment {
                @Override
                public Dialog onCreateDialog(Bundle savedInstanceState) {
                    final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                    // Get the layout inflater
                    LayoutInflater inflater = getActivity().getLayoutInflater();
                    ArrayAdapter<String> adapter = new ArrayAdapter<String>(main, R.layout.detlistitem, androidServer.ladd.getCachedLadder());
                    // Inflate and set the layout for the dialog
                    // Pass null as the parent view because it's going in the dialog layout
                    View listFrameview = inflater.inflate(R.layout.ladder, null);
                    {
                          TextView ladderlab = (TextView)listFrameview.findViewById(R.id.ladderlab);
                          String s = "on "+androidServer.ladd.getCacheTime()+" your rk: "+androidServer.ladd.userRank;
                          ladderlab.setText(s);
                    }
                    final ListView ladder = (ListView)listFrameview.findViewById(R.id.ladderList);
                    ladder.setAdapter(adapter);
                    ladder.setOnItemClickListener(new OnItemClickListener() {
                            @Override
                            public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
                                androidServer.ladd.lastClicked = position;
                            }
                        });
                    builder.setView(listFrameview);

                    builder.setPositiveButton("Challenge", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            int i = androidServer.ladd.lastClicked;
//                                showMessage("selected item "+i);
                            if (i>=0) {
                                ladderChallenge(i);
                            }
                                DetListDialogFragment.this.getDialog().dismiss();
                        }
                    })
                    .setNeutralButton("Reload", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                          androidServer.ladd.resetCache();
                          androidServer.startLadderView(eidogodir);
                          DetListDialogFragment.this.getDialog().dismiss();
                        }
                    })
                    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                          DetListDialogFragment.this.getDialog().dismiss();
                        }
                    });
                    return builder.create();
                }
            }
            final DetListDialogFragment msgdialog = new DetListDialogFragment();
            msgdialog.show(main.getSupportFragmentManager(),"message");
      }
      @Override
      public String getName() {return "ladder";}
    });
        androidServer.ladd.checkCache(eidogodir);
        androidServer.startLadderView(eidogodir);
  }
  
  private void ladderChallenge(int pos) {
        if (pos<0||pos>=androidServer.ladd.ridList.length) {
            showMessage("Problem with item at pos "+pos);
            return;
        }
        String rid = androidServer.ladd.ridList[pos];
        System.out.println("challenging "+rid);
        androidServer.ladderChallenge(rid,pos);
    }
  
  private void showMoreButtons() {
    System.out.println("showing more buttons");
    class MoreButtonsDialogFragment extends DialogFragment {
      private final MoreButtonsDialogFragment dialog = this;
      @Override
      public Dialog onCreateDialog(Bundle savedInstanceState) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        // Get the layout inflater
        LayoutInflater inflater = getActivity().getLayoutInflater();

        // Inflate and set the layout for the dialog
        // Pass null as the parent view because its going in the dialog layout
        View v = inflater.inflate(R.layout.other_buttons, null);

        Button bdebug = (Button)v.findViewById(R.id.loadSgf);
        bdebug.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            System.out.println("loading sgf");
            loadSgf();
            changeState(guistate.play);
            Game.createDebugGame();
            dialog.dismiss();
          }
        });

                Button bgamemsg = (Button)v.findViewById(R.id.gamemsg);
                bgamemsg.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View vv) {
                        addGameMessage();
                        dialog.dismiss();
                    }
                });

                Button bladder19 = (Button)v.findViewById(R.id.ladder19);
                bladder19.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View vv) {
                        viewLadder(Ladder.LADDER19x19);
                        dialog.dismiss();
                    }
                });

                Button bladder9 = (Button)v.findViewById(R.id.ladder9);
                bladder9.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View vv) {
                        viewLadder(Ladder.LADDER9x9);
                        dialog.dismiss();
                    }
                });

        RadioButton bserver1 = (RadioButton)v.findViewById(R.id.dgs);
        bserver1.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            chosenServer=0;
            if (server!=null) server.closeConnection();
            server=null;
            dialog.dismiss();
          }
        });
        RadioButton bserver2 = (RadioButton)v.findViewById(R.id.devdgs);
        if (chosenServer==1) bserver2.setChecked(true);
        bserver2.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            chosenServer=1;
            if (server!=null) server.closeConnection();
            server=null;
            dialog.dismiss();
          }
        });
        RadioButton blogin1 = (RadioButton)v.findViewById(R.id.log1);
        blogin1.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            chosenLogin=0;
            if (server!=null) server.closeConnection();
            server=null;
            dialog.dismiss();
          }
        });
        RadioButton blogin2 = (RadioButton)v.findViewById(R.id.log2);
        if (chosenLogin==1) blogin2.setChecked(true);
        blogin2.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            chosenLogin=1;
            if (server!=null) server.closeConnection();
            server=null;
            dialog.dismiss();
          }
        });

        Button breviews = (Button)v.findViewById(R.id.reviews);
        breviews.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            System.out.println("game reviews");
            Reviews.contReviews();
            dialog.dismiss();
          }
        });
        Button beidogo = (Button)v.findViewById(R.id.copyEidogo);
        beidogo.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            System.out.println("copy eidogo");
            new CopyEidogoTask().execute("noparms");
            dialog.dismiss();
          }
        });
        Button bcycle = (Button)v.findViewById(R.id.cycleStates);
        bcycle.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            changeState(guistate.nogame);
                        dialog.dismiss();
          }
        });
        Button bskip = (Button)v.findViewById(R.id.skipGame);
        bskip.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            System.out.println("skip game");
            skipGame();
            dialog.dismiss();
          }
        });
        Button bresign= (Button)v.findViewById(R.id.resign);
        bresign.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            System.out.println("resign game");
            resignGame();
            dialog.dismiss();
          }
        });
        Button bforums= (Button)v.findViewById(R.id.forums);
        bforums.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View vv) {
            System.out.println("Forums");
            Forums.show();
            dialog.dismiss();
          }
        });

        builder.setView(v);
        return builder.create();
      }
    }
    MoreButtonsDialogFragment dialog = new MoreButtonsDialogFragment();
    dialog.show(getSupportFragmentManager(),"more actions");
  }

  int toastline = 0;
  public void longToast(String msg, int secs) {
      final String[] ss = msg.split("\n");
      if (ss.length>4) {
          int ntics = ss.length/4;
          if (ntics*4<ss.length) ++ntics;
          toastline=0;
          String s = ss[toastline];
          for (int i=toastline+1;i<toastline+4&&i<ss.length;i++)
              s+="\n"+ss[i];
          Toast.makeText(getBaseContext(), s, Toast.LENGTH_LONG).show();
          new CountDownTimer(1000*ntics, 1000) {
              public void onTick(long millisUntilFinished) {
                  toastline+=4;
                  String s = ss[toastline];
                  for (int i=toastline+1;i<toastline+4&&i<ss.length;i++)
                      s+="\n"+ss[i];
                  Toast.makeText(getBaseContext(), s, Toast.LENGTH_LONG).show();
              }
              public void onFinish() {}
          }.start();
      } else {
          Toast.makeText(getBaseContext(), msg, Toast.LENGTH_LONG).show();
      }
  }
}




Java Source Code List

fr.xtof54.jsgo.AndroidServerConnection.java
fr.xtof54.jsgo.EventManager.java
fr.xtof54.jsgo.Forums.java
fr.xtof54.jsgo.GUI.java
fr.xtof54.jsgo.Game.java
fr.xtof54.jsgo.GoJsActivity.java
fr.xtof54.jsgo.Ladder.java
fr.xtof54.jsgo.Message.java
fr.xtof54.jsgo.PrefUtils.java
fr.xtof54.jsgo.Reviews.java
fr.xtof54.jsgo.ServerConnection.java
fr.xtof54.jsgo.WebAppInterface.java
org.json.CDL.java
org.json.CookieList.java
org.json.Cookie.java
org.json.HTTPTokener.java
org.json.HTTP.java
org.json.JSONArray.java
org.json.JSONException.java
org.json.JSONML.java
org.json.JSONObject.java
org.json.JSONString.java
org.json.JSONStringer.java
org.json.JSONTokener.java
org.json.JSONWriter.java
org.json.Kim.java
org.json.Property.java
org.json.XMLTokener.java
org.json.XML.java