@Override
  public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    switch (item.getItemId()) {
        // Respond to the action bar's Up/Home button
      case android.R.id.home:
        finish();
      case R.id.action_save:
        DatabaseHandler databaseHandler = new DatabaseHandler(AddClinicalNotesActivity.this);
        try {
          if (historyObj._date != null) databaseHandler.addHistory(historyObj);
          if (examObj._date != null) databaseHandler.addExam(examObj);
          if (treatmentOb._date != null) databaseHandler.addTreatment(treatmentOb);
          if (Other_Notes_Activity.otherObj != null && Other_Notes_Activity.otherObj.size() > 0) {
            for (int i = 0; i < Other_Notes_Activity.otherObj.size(); i++) {
              databaseHandler.addOther(Other_Notes_Activity.otherObj.get(i));
            }
            Other_Notes_Activity.otherObj.clear();
          }

        } catch (Exception e) {
          e.printStackTrace();
        }
        finish();
        return true;
    }
    return super.onOptionsItemSelected(item);
  }
  private static void readLinkFile(boolean isHighway) {
    System.out.println("read link file...");
    int debug = 0;
    try {
      FileInputStream fstream =
          new FileInputStream(root + "/" + (isHighway ? highwayLinkFile : arterialLinkFile));
      DataInputStream in = new DataInputStream(fstream);
      BufferedReader br = new BufferedReader(new InputStreamReader(in));
      String strLine;

      while ((strLine = br.readLine()) != null) {
        debug++;
        String[] nodes = strLine.split(";");
        int linkId = Integer.parseInt(nodes[0]);
        String allDir = nodes[1];
        String streetName = nodes[2];
        int funcClass = Integer.parseInt(nodes[3]);
        ArrayList<PairInfo> nodeList = getPairListFromStr(nodes[4]);
        int speedCat = Integer.parseInt(nodes[5]);
        String dirTravel = nodes[6];
        int startNode = Integer.parseInt(nodes[7]);
        int endNode = Integer.parseInt(nodes[8]);

        LinkInfo linkInfo =
            new LinkInfo(
                linkId,
                funcClass,
                streetName,
                startNode,
                endNode,
                nodeList,
                dirTravel,
                speedCat,
                allDir);

        if (isHighway) highwayLinkList.add(linkInfo);
        else arterialLinkList.add(linkInfo);

        if (debug % 100000 == 0) System.out.println("record " + debug + " finish!");
      }
    } catch (Exception e) {
      // TODO: handle exception
      e.printStackTrace();
      System.err.println("Error Code: " + debug);
    }
    System.out.println("read link file finish!");
  }
  private static void generateKML(boolean isHighway) {
    System.out.println("generate link kml...");
    try {
      FileWriter fstream =
          new FileWriter(root + "/" + (isHighway ? highwayKmlFile : arterialKmlFile));
      BufferedWriter out = new BufferedWriter(fstream);
      out.write("<kml><Document>");
      ArrayList<LinkInfo> linkList = isHighway ? highwayLinkList : arterialLinkList;
      for (int i = 0; i < linkList.size(); i++) {
        LinkInfo link = linkList.get(i);
        int linkId = link.getLinkId();
        int funcClass = link.getFuncClass();
        String streetName = link.getStreetName();
        if (streetName.contains("&")) streetName = streetName.replaceAll("&", " and ");
        ArrayList<PairInfo> nodeList = link.getNodeList();

        String kmlStr = "<Placemark><name>Link:" + linkId + "</name>";
        kmlStr += "<description>";
        kmlStr += "Class:" + funcClass + "\r\n";
        kmlStr += "Name:" + streetName + "\r\n";
        kmlStr += "</description>";
        kmlStr += "<LineString><tessellate>1</tessellate><coordinates>";
        for (int j = 0; j < nodeList.size(); j++) {
          PairInfo node = nodeList.get(j);
          kmlStr += node.getLongi() + "," + node.getLati() + ",0 ";
        }
        kmlStr += "</coordinates></LineString></Placemark>\n";

        out.write(kmlStr);
      }
      out.write("</Document></kml>");
      out.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println("generate link kml finish!");
  }
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (data != null) {
      if ((data.getStringExtra("activity").equals("history")) && (requestCode == REQUEST_CODE)) {

        try {
          historyObj = data.getExtras().getParcelable("history_obj");
        } catch (Exception e) {

          e.printStackTrace();
        }

      } else if ((data.getStringExtra("activity").equals("exam"))
          && (requestCode == REQUEST_CODE)) {
        examObj = data.getExtras().getParcelable("exam_obj");
      } else if ((data.getStringExtra("activity").equals("treatment"))
          && (requestCode == REQUEST_CODE)) {
        treatmentOb = data.getExtras().getParcelable("treat_obj");
      } else if ((data.getStringExtra("activity").equals("other"))
          && (requestCode == REQUEST_CODE)) {
        otherObj = data.getExtras().getParcelable("other_obj");
      }
    }
  }
  public static void saveAll(Personnage saver) {
    PrintWriter _out = null;
    if (saver != null) _out = saver.get_compte().getGameThread().get_out();

    set_state((short) 2);

    try {
      GameServer.addToLog("Lancement de la sauvegarde du Monde...");
      Ancestra.isSaving = true;
      SQLManager.commitTransacts();
      SQLManager.TIMER(false); // Arrête le timer d'enregistrement SQL

      Thread.sleep(10000);

      GameServer.addToLog("Sauvegarde des personnages...");
      for (Personnage perso : Persos.values()) {
        if (!perso.isOnline()) continue;
        Thread.sleep(100); // 0.1 sec. pour 1 objets
        SQLManager.SAVE_PERSONNAGE(perso, true); // sauvegarde des persos et de leurs items
      }

      Thread.sleep(2500);

      GameServer.addToLog("Sauvegarde des guildes...");
      for (Guild guilde : Guildes.values()) {
        Thread.sleep(100); // 0.1 sec. pour 1 guilde
        SQLManager.UPDATE_GUILD(guilde);
      }

      Thread.sleep(2500);

      GameServer.addToLog("Sauvegarde des percepteurs...");
      for (Percepteur perco : Percepteurs.values()) {
        if (perco.get_inFight() > 0) continue;
        Thread.sleep(100); // 0.1 sec. pour 1 percepteur
        SQLManager.UPDATE_PERCO(perco);
      }

      Thread.sleep(2500);

      GameServer.addToLog("Sauvegarde des maisons...");
      for (House house : Houses.values()) {
        if (house.get_owner_id() > 0) {
          Thread.sleep(100); // 0.1 sec. pour 1 maison
          SQLManager.UPDATE_HOUSE(house);
        }
      }

      Thread.sleep(2500);

      GameServer.addToLog("Sauvegarde des coffres...");
      for (Trunk t : Trunks.values()) {
        if (t.get_owner_id() > 0) {
          Thread.sleep(100); // 0.1 sec. pour 1 coffre
          SQLManager.UPDATE_TRUNK(t);
        }
      }

      Thread.sleep(2500);

      GameServer.addToLog("Sauvegarde des enclos...");
      for (Carte.MountPark mp : MountPark.values()) {
        if (mp.get_owner() > 0 || mp.get_owner() == -1) {
          Thread.sleep(100); // 0.1 sec. pour 1 enclo
          SQLManager.UPDATE_MOUNTPARK(mp);
        }
      }

      Thread.sleep(2500);

      GameServer.addToLog("Sauvegarde des Hdvs...");
      ArrayList<HdvEntry> toSave = new ArrayList<HdvEntry>();
      for (HDV curHdv : Hdvs.values()) {
        toSave.addAll(curHdv.getAllEntry());
      }
      SQLManager.SAVE_HDVS_ITEMS(toSave);

      Thread.sleep(10000);

      GameServer.addToLog("Sauvegarde effectuee !");

      set_state((short) 1);
      // TODO : Rafraichir

    } catch (ConcurrentModificationException e) {
      if (saveTry < 10) {
        GameServer.addToLog("Nouvelle tentative de sauvegarde");
        if (saver != null && _out != null)
          SocketManager.GAME_SEND_CONSOLE_MESSAGE_PACKET(
              _out, "Erreur. Nouvelle tentative de sauvegarde");
        saveTry++;
        saveAll(saver);
      } else {
        set_state((short) 1);
        // TODO : Rafraichir
        String mess = "Echec de la sauvegarde apres " + saveTry + " tentatives";
        if (saver != null && _out != null)
          SocketManager.GAME_SEND_CONSOLE_MESSAGE_PACKET(_out, mess);
        GameServer.addToLog(mess);
      }

    } catch (Exception e) {
      GameServer.addToLog("Erreur lors de la sauvegarde : " + e.getMessage());
      e.printStackTrace();
    } finally {
      SQLManager.commitTransacts();
      SQLManager.TIMER(true); // Redémarre le timer d'enregistrement SQL
      Ancestra.isSaving = false;
      saveTry = 1;
    }
  }