/*
 * emissionHtmlEnRetard ??? 
 * option C getConfig en oubli!
 * verifier si PIM accessible
 *  option pour afficher memoire 
 *  prevoir un controle de la memoire selon fichiers à lire/envoyer
 * afficher banière
 *
 * Copyright (c) 2007, Sun Microsystems, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of Sun Microsystems nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package example.http;

import com.nokia.mid.ui.*;
import java.util.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;

// import javax.microedition.lcdui.DateField;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.pim.*;
// JSR 179 
// import javax.microedition.location.*;
// import javax.microedition.;
import java.io.*;


public class HttpTest extends MIDlet implements CommandListener, Runnable {
  PIM singleton=PIM.getInstance();
//  boolean sendMailActif=false;
 
  final int MAXRECEIVEHTML=20000;
  
  String ContentType="Content-Type: multipart/mixed;\n boundary=";
  String mimeSeparator="----123456789";
  String enteteMime="";
  String epilogueMime="";
  boolean afficherFirst=true;
  boolean multipartDone=false;
 boolean smtpOpen=false;
 // boolean dejavu=false;
   StringBuffer totalRapport = new StringBuffer("");  
   boolean uploadByMailReussi=false;
boolean uploadByPostReussi=false;
final String SMTPSERVER="socket://smtp.orange.fr:25";
boolean emissionHtmlEnRetard=false;
boolean emissionSmtpEnRetard=false;
final int DATECOURTE=1;
// final int DATELONGUE=2;
final int HHMMSS=3;


// int final TIMEOUT179=20;
int timeout179=0;
int jsr179Accuracy=10000;
  

//          InputStream ism =null;
//        OutputStream osm =null;
// partagés entre ouvrir / fermer smtp et mailX ou rapporte
          InputStream ismX =null;
        OutputStream osmX =null;
      SocketConnection scX =null;
      
    final int insisteHtmlMax=2;
    final int insisteSmtpMax=2;
    // contante pour rapportefichier
    final int CONTENU=1;
    final int TAILLE=2;
    final int ENCODEDBASE64=3;
    final int AVECCRLF=4;
    // buffer lecture fichier
    final int TAILLEBUFFERFICHIER=64000;
    
    final int FINOPTMAX=99999;
   String jsr179Version=null; 
   String jsr256Version=null; 
    final String HEXA ="0123456789ABCDEF";
   
    String np="";
   
    
     /**
      * This character array provides the alphabet map from RFC1521.
      */
     private final  char ALPHABETRFC1521[] = {
        //       0    1    2    3    4    5    6    7
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',  // 0
                'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',  // 1
                'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',  // 2
                'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',  // 3
                'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',  // 4
                'o', 'p', 'q', 'r', 's', 't', 'u', 'v',  // 5
                'w', 'x', 'y', 'z', '0', '1', '2', '3',  // 6
                '4', '5', '6', '7', '8', '9', '?', '/'  // 7
        };
     
 
     /**
      * Encodes 1, 2, or 3 bytes of data as 4 Base64 chars.
      *
      * @param in buffer of bytes to encode
      * @param len how many bytes to encode
      * @param out buffer to put the output in
      */
     private  void encodeQuantumPo(byte in[], int zero, int len,  char out[]) {
    
         char cc=' ';
        byte a = 0, b = 0, c = 0;
         int inOffset=zero;
         int outOffset=0;
         a = in[inOffset];
         out[outOffset] = ALPHABETRFC1521[(a >>> 2) & 0x3F];
         if (len > 2) {
             
             b = in[inOffset + 1];
             c = in[inOffset + 2];
       
            cc=ALPHABETRFC1521[((a << 4) & 0x30) +
                                          ((b >>> 4) & 0xf)];
       
             out[outOffset + 1] =cc;
             
             cc=ALPHABETRFC1521[((b << 2) & 0x3c) +
                                           ((c >>> 6) & 0x3)];
             out[outOffset + 2] =cc ;
       
             cc=ALPHABETRFC1521[c & 0x3F];
             out[outOffset + 3] = cc;
             if (cc=='+')DEBUG(8439,"en encode généré + en 4ème" );
         } else if (len > 1) {
             b = in[inOffset + 1];
             out[outOffset + 1] = ALPHABETRFC1521[((a << 4) & 0x30) +
                                          ((b >>> 4) & 0xf)];
            out[outOffset + 2] =  ALPHABETRFC1521[((b << 2) & 0x3c) +
                                           ((c >>> 6) & 0x3)];
            out[outOffset + 3] = '=';
      
         } else {
             out[outOffset + 1] = ALPHABETRFC1521[((a << 4) & 0x30) +
                                          ((b >>> 4) & 0xf)];
            out[outOffset + 2] = '=';
            out[outOffset + 3] = '=';
      
         }
     }
      
  public void sendMailX(String subjectEmail,String msgEmail) {
//      sendMailActif=true;
      boolean saveABANDON=ABANDON;
      openSmtp(2,subjectEmail);
      ABANDON=saveABANDON;
 try{     osmX.write(msgEmail.getBytes());
 }catch (Exception e){
     ABEND(31441,"sendmail",e);
     return;
 }
      closeSmtpLogReply();
 
 //  sendMailActif=false;
 } 


public boolean sendMailCompactReussi(int appel,String subjectEmail,String msgEmail) {
      // pourrait partahger ouvrir/fermer!
    
//    DEBUG(19833,"debut de sendMailCompact:"+appel);
//    ABEND(19833,"forcé pour test");
//    if (ABANDON) return;
    
//     DEBUG(19833,"compact va ouvrir smtp pour:"+msgEmail.length());
//      sendMailActif=true;
      smtpOpen=true; 
  //    ABANDON=false;
  //    DEBUG(4323,"debut de ouvrirsmtp to:"+toEmail);
  //    DEBUG(4324,"suite de ouvrirsmtp from:"+fromEmail);
  //    log("debut de ouvrirsmtp to:"+toEmail);
  //    log("suite de ouvrirsmtp from:"+fromEmail);
      SocketConnection scmc=null; // =new SocketConnection();
      OutputStream osmc =null;
      InputStream ismc =null;
 
      try{
  //    scmc =  (SocketConnection) Connector.open("socket://smtp.orange.fr:25"); // =new SocketConnection();
      scmc =  (SocketConnection) Connector.open(SMTPSERVER); // =new SocketConnection();
      }catch (Exception  a){
          
        DEBUG(4324,"socket connection exception a:",a);
  //      ABEND(43241,"socket connection exception:",a);
          try{scmc.close();}
          catch(Exception xx){ERROR(41410,"xx1",xx);}
          if (scmc!=null) scmc=null;
        return(false);  
      }

      //    DEBUG(133331,"SendMail:"+subjectEmail);
      try {
      ismc = scmc.openInputStream();
      }catch (IOException e){
          DEBUG(0,"OpenIntputStream ",e);
          try{ismc.close();}
          catch(Exception xx){ERROR(41417,"xx1",xx);}
          if (ismc!=null) ismc=null;
          try{scmc.close();}
          catch(Exception xx){ERROR(41418,"xx1",xx);}
          if (scmc!=null) scmc=null;
        return(false);  
 
      }
        try{   osmc = scmc.openOutputStream();
   //   DEBUG(1333311,"OpenInputStream");
       }catch (IOException e){
 //         ABEND(0,"OpenOutputStream ",e);
          DEBUG(0,"OpenOutputStream ",e);
          try{osmc.close();}
          catch(Exception xx){ERROR(41421,"xx1",xx);}
          if (osmc!=null) osmc=null;
          try{ismc.close();}
          catch(Exception xx){ERROR(41425,"xx1",xx);}
          if (ismc!=null) ismc=null;
          try{scmc.close();}
          catch(Exception xx){ERROR(41426,"xx1",xx);}
          if (scmc!=null) scmc=null;
        return(false);  
 
      }
      try{ 
     
         osmc.write(("HELO 0642419118" + "\r\n").getBytes()); 
         osmc.write(("MAIL FROM: <"+ fromEmail +">\r\n").getBytes());
         osmc.write(("RCPT TO: <"+ toEmail + ">\r\n").getBytes());
         osmc.write("DATA\r\n".getBytes());
         // stamp the msg with date
         osmc.write(("Date: " + new Date() + "\r\n").getBytes()); 
         osmc.write(("From: "+fromEmail+"\r\n").getBytes());
         osmc.write(("To: "+toEmail+"\r\n").getBytes());
         osmc.write(("Subject: "+subjectEmail+"\r\n\r\n").getBytes());
         osmc.write(msgEmail.getBytes());
         osmc.write(epilogueMime.getBytes());
         osmc.write((".\r\n").getBytes()); // fini!
         osmc.write(("quit\r\n").getBytes()); // fini!
         osmc.close();
      } catch(IOException e) {
            DEBUG (1616,"IO en SendmaliCompact",e);
          DEBUG(0,"OpenOutputStream ",e);
          try{osmc.close();}
          catch(Exception xx){ERROR(41414,"xx1",xx);}
          if (osmc!=null) osmc=null;
          try{ismc.close();}
          catch(Exception xx){ERROR(41415,"xx1",xx);}
          if (ismc!=null) ismc=null;
          try{scmc.close();}
          catch(Exception xx){ERROR(41415,"xx1",xx);}
          if (scmc!=null) scmc=null;
        return(false);  
         }
 
 //     fermerSmtp();
 
     //    DcEBUG(133331,"fin de contenu");
         logSmtpResponse(1,ismc);     
     //    StringBuffer si=new StringBuffer();
 
          try{osmc.close();}
          catch(Exception xx){ERROR(41411,"xx1",xx);}
          if (osmc!=null) osmc=null;
          try{ismc.close();}
          catch(Exception xx){ERROR(41412,"xx1",xx);}
          if (ismc!=null) ismc=null;
          try{scmc.close();}
          catch(Exception xx){ERROR(41413,"xx1",xx);}
          if (scmc!=null) scmc=null;
  // DEBUG(454545,"SendMailCompact termine");
         smtpOpen=false;
         return (true);
      }
     
 
 

 public void openSmtp(int appel,String subjectEmail) {
 // voi mailactif ?    
     
     if (smtpOpen){
         ABEND (198392,"Smtp récursif appel:"+appel);
         return;
     }
     smtpOpen=true;  // protection reentrance!
     ECRAN("","va ouvrir smtp");
 //    sendMailActif=true;
  //    DEBUG(4323,"debut de ouvrirsmtp to:"+toEmail);
  //    DEBUG(4324,"suite de ouvrirsmtp from:"+fromEmail);
  //    log("debut de ouvrirsmtp to:"+toEmail);
  //    log("suite de ouvrirsmtp from:"+fromEmail);
      SocketConnection sc=null; // =new SocketConnection();
      try{
      sc =  (SocketConnection) Connector.open(SMTPSERVER); // =new SocketConnection();
      }catch (Exception  a){
          
   //     DEBUG(4324,"socket connection exception:"+a);
        ABEND(43242,"socket connection exception:",a);
        return;  
      }
 //    DEBUG(133331,"SendMail:"+subjectEmail);
      try {
      ismX = sc.openInputStream();
      }catch (IOException e){
          ABEND(0,"OpenIntputStream ",e);
      }
        try{   osmX = sc.openOutputStream();
   //   DEBUG(1333311,"OpenInputStream");
       }catch (IOException e){
          ABEND(0,"OpenOutputStream ",e);
      }
      try{ 
     
         osmX.write(("HELO 0642419118" + "\r\n").getBytes()); 
                }catch (IOException e){
          ABEND(514410,"write ",e);
      }
        DEBUG(1333315,"Helo fait");
        
        try{
         osmX.write(("MAIL FROM: <"+ fromEmail +">\r\n").getBytes());
         osmX.write(("RCPT TO: <"+ toEmail + ">\r\n").getBytes());
         osmX.write("DATA\r\n".getBytes());
         // stamp the msg with date
         osmX.write(("Date: " + new Date() + "\r\n").getBytes()); 
         osmX.write(("From: "+fromEmail+"\r\n").getBytes());
         osmX.write(("To: "+toEmail+"\r\n").getBytes());
         osmX.write(("Subject: "+subjectEmail+"\r\n\r\n").getBytes());
         } catch(IOException e) {
            ERROR(454545,"osmX.write",e);
         }
//      sendMailActif=false;
      DEBUG(1333315,"EnTete fait");
      logSmtpResponse(2,ismX);
        } 


 public void logSmtpResponse(int appel,InputStream is){
         // debug
         StringBuffer sb = new StringBuffer();
         int c = 0;
        try{
         while (((c = is.read()) != -1) ) {
            sb.append((char) c);
         }
        }catch (Exception e){
            // sans doute fin de donnees ?
    //        ABEND(1333331,"Exception ism.read\n-----------------\n"+sb.toString()+"\n----------",e);
    //        return;
        }
         DEBUG(12952,"SMTP server response appel:"+appel+"\n"+ sb.length()+"\n" + sb.toString());      
//         log("\nSMTP server response -"+appel+"\n"+ sb.length()+"\n" + sb.toString());      
  //       DEBUG(12952,"....");      
  //       log("\n......");      
    
 }
 public void closeSmtpLogReply() {
     try{
         osmX.write(epilogueMime.getBytes());
         osmX.write((".\r\n").getBytes()); // fini!
         osmX.write(("quit\r\n").getBytes()); // fini!
         osmX.close();
     //    DEBUG(133331,"fin de contenu");
         logSmtpResponse(1,ismX);     
     //    StringBuffer si=new StringBuffer();
 
      } catch(IOException e) {

      } finally {
         try {
            if(ismX != null) {
               ismX.close();
            }
            if(osmX != null) {
               osmX.close();
            }
           if(scX != null) {
               scX.close();
            }
         } catch(IOException e) {
            ERROR (5411,"scX close ",e);
         }
      }    
//      ABANDON=saveABANDON;
 //  sendMailActif=false;
   smtpOpen=false;
    } 


 // GAFFE pour limiter charge option
 
  String smtpServerAddress="smtp.orange.fr";
  String fromEmail="0643214680@orange.fr";  // modifable par <
  String toEmail="flavigny@free.fr"; // modifiable par >
  String excAbendSend="";
   final String version="1.0037" ;
   String racine="http://www.logsm.net";
   final String AMORCE="http://mobile.orange.fr/0/accueil/Retour?SA=CHADEPTFCGEO";
   final String LOGSMDOTPHP="/logsmpo.php";
       
int ch=0;
   StringBuffer bm = new StringBuffer();

  String TROUVE="T";
  
  String lastUrl="";
//  boolean cgopen=false;
//  boolean oldopen=true;
  boolean backlightDone=false;
  
  int periodeHorloge=10;
  int BACKLIGHTPERIODE=5;
  
  StringBuffer bbrut = new StringBuffer();

  int NBMAXREDIR=8;
 //      int po3f;  
//  HttpConnection cg = null;  // pour getUrl
//  HttpConnection cm = null;  // pour mail
//  InputStream is=null;
  
  int gapSecondes=-1;
  int shutDown=-1;
   final String PO="Po";
   String HOMEFSLOCAL="";   
//   String HOMENOKIA2610="file:///C:/predefgallery/Logsm/";
     String HOMENOKIA2610="file:///C:/predefgallery/predefrecordings";
   
   final String NOKIA2610="Nokia2610";  
   final String NOKIA5800="Nokia5800";  
   final String SAMSUNGC3050="SamsungC3050";
   final String HOMESAMSUNGC3050="file:///C:/predefgallery/predefrecordings";
 //  String FICHIER="";
   String FICHIERABEND="";
   String pileouface="";  // nom de fichier/chemin reçu par option "!"
   String PILE="";
   String FACE="";
   boolean fileCreated=false;
   final String HEUREMATIN="08:00:00";
   final String HEURENUIT="20:00:00";
   StringBuffer resumeTout=new StringBuffer(); 
   String stamp="";
   long nowMilli=0;
   long startMilli=-1;
   long nextMilli=-1;
   
   String globalTete="";
    boolean ABANDON=false;
   String numTelephone="";
   String modeleTelephone="";
   
   int GLOBiter=0;
   int GLOBup=0;   // compte les émissions par html
 
   String lat="";
   String lon="";
//   String latLonEcran="";

//   OutputConnection globalOs = null;
   
   String lastMailRc = "";
//   String sortieMailRc = "";
 //  int mailCount=0;
   final int WAITECRAN=5;
   final int WAITGRAVE=5;
//   String xyxy="";
//   String xyxyEcran="";
   String afficher;
   String trouve=""; // sera T quand localisé
 //  int attendu=0; // cumul des attentes à décompter de inter-coups
  // aux ordres de l'url
  int locSucces=0;
  int nbGet=0;
//   String Xoptions=""; // obsolete JSR179 ?
   String PropDescription="";
   
// options seront modifiées par config.txt puis réponses
   boolean optionDump=false;
   boolean optionNoTrafic=false;
   boolean optionFirst=false;
   boolean optionQuit=false;
   boolean optionJsr179=false;
   boolean optionTous=false;
   boolean optionPack=false;
   boolean optionVoir=false;
   boolean optionFatigue=false;
   boolean optionRaz=false;
   boolean optionApi=false;
   boolean optionGetConfig=false;
   boolean optionDouble=false;
   boolean optionListe=false;
   boolean optionZigZag=false;
   boolean optionInternetMax=false;
//   boolean optionMemAv=false
   boolean optionMail=false;
   boolean optionInternetNuit=false;
   boolean optionTelephone=false;
   boolean optionAutoUrl=false; // pas modifiable 
   boolean optionBacklight=false; // pas modifiable 
   boolean optionWriteFsLocal=true;
   boolean optionEcran=true;
//   boolean optionDebug=false;   // pour l'avoir avant prise en cahrge de l'option
   boolean optionGrave=true;  //pour l'avoir au début
   boolean optionLog=true;  //pour l'avoir au début
//   boolean anyDebug=true;  // on part en debug
   boolean optionFichier=false;
   boolean optionHorloge=false;
   String globalTitre="";
   String globalTexte="";
   int finOpt=FINOPTMAX;
   //
   String sessionID="" ; //a partir de premiere localisation d'orange
  int iterations;
  long periodeSecondes;
  int periodeGroupage;
  
   int             mail2Number=0;
   String              mail2Subject="";
   String              mail2Contenu="";
   
   boolean premsConfig=true;
   
   // Command probablemen t pas utilisé, en souvenir de modèle
    /** User interface command to exit the current application. */
    private Command exitCommand = new Command("Exit", Command.EXIT, 2);

    /** User interface command to issue an HTTP GET request. */
  //  private Command getCommand = new Command("Start", Command.SCREEN, 1);

    /** User interface command to choose a configuration */
  //  private Command chooseCommand = new Command("Choose", Command.SCREEN, 2);

    /** User interface command to Add a new location. */
  //  private Command addCommand = new Command("Add", Command.SCREEN, 1);

    /** User interface command to save a new location. */
//    private Command addSaveCommand = new Command("OKsave", Command.SCREEN, 1);

    /** User interface command to confirm current operation. */
//    private Command okCommand = new Command("OKconfig", Command.OK, 1);

    /** User interface command to abort current operation. */
//    private Command cancelCommand = new Command("Cancel", Command.CANCEL, 1);

    /** The current display object. */
    private Display display;

    /** The configuration  */
    private String configRecue="";
    private String configPrev="";  // pour ne pas decoder si identique 
  
    // prochaine url a ouvrir (mise par getandfollow quand site dit 301 ou 302)
    private String urlNext;
  
        /** Current command to process. */
    private Command currentCommand;

    /** The current command processing thread. */
    private Thread commandThread;

    /** Current attempt count. */
    private int attempt;
    
class NokiaS40LightThread extends Thread {   //1
    // 20100227 - semble fonctionner si au démarrage
    // pas programmé l'exticntion!
    //
    public void run() {
       // premier essai pour voir   
       DEBUG(1111,"LightThread...");
       //   System.out.println("lightTread lancé! "+heureCourte());
       while(true){
          //         if (optionBacklight) {
          // STD ou nokia  
          // pas souvenir de ce STD ou nokia ?
          try{
            DeviceControl.setLights(0, 100);
          }catch (Exception e){
             DEBUG(1111,"Nokia hardware? cron");
          }
       
          try {
              Thread.sleep(1000*BACKLIGHTPERIODE);
          } catch (InterruptedException ex) {
              DEBUG(1111,"Nokia sleep?");
          } // try
       } //while
    }  // run
  }  // LightThread
 

    
    /** Initialize the MIDlet with a handle to the current display */
public HttpTest() {
     // pas d ECRAN avant ce display!
     display = Display.getDisplay(this);
   }

void beep(){
   if(modeleTelephone.equals(NOKIA2610))  {
    AlertType.ERROR.playSound(Display.getDisplay(this));
   }else{
      DEBUG(19911,"beep");
   }
  }    

void lightOn(){
// np="lightOn";"   
 if (optionVoir){   
  if(modeleTelephone.equals(NOKIA2610))  {
 // ne fonctionne pas
      try{
              // nom long pour la frime
              com.nokia.mid.ui.DeviceControl.setLights(0, 100); 
      
     }catch (Exception e){
     }
    }
  // autres modèles ...
} //option Voir
}

void newDisplay(int appel,String titre,String texte){
    // range dans variables globales l'écran à affichier par clockDisplay
    // attetion pas d'attente
    // conserver les paraametres sn global
    //   globalAppel=appel;
    globalTitre=titre;
    globalTexte=texte;
    // si DEBUG ou ABEND ajouter le numéro d'appel
    if (appel!=0){
        if (appel>0) {globalTete = "["+appel+"]";}
        else {globalTete = "{"+(-appel)+"}";}
    }else{globalTete="";}
    clockDisplay();  
}

void clockDisplay(){
    // appellé par newDisplay ou waitSecondes!
    // avrec délai à prochain scan ?
    // BUG 24 heures
    String resteAvantProchain="";
    if (nextMilli>=0)  resteAvantProchain= "<"+(nextMilli-nowMs())/1000;
    
    TextBox tc = new TextBox(globalTete+date(HHMMSS)+resteAvantProchain+"\n"+
                    globalTitre, globalTexte.toString(), globalTexte.length(), 0);
 
    display.setCurrent(tc);
      //     display = Display.getDisplay(this); // supprime 20100302
    lightOn();   
}

// adapter à heure en minutes

void waitSecondsXX( int appel, long n) {
//    np="waitSeconds";
  // essai horloge toutes les 10 secondes (fixé par periodeHorloge) !
     long inw;
     
     for (inw=1; inw<=n;++inw) {
        try {
                  Thread.sleep(1000);
        }  catch (Exception e) {
              //DEBUG non disponible (serait recursif!)
    //          ERROR(12334,"ERREUR Sleep 1000 "+e);
        }
        if (optionHorloge && (periodeHorloge*(inw/periodeHorloge)==inw)) {clockDisplay();}
    }
}

void waitMilli( int appel, long n) {
//    np="waitSeconds";
  // essai horloge toutes les 10 secondes (fixé par periodeHorloge) !
        try {
                  Thread.sleep(n);
        }  catch (Exception e) {
              //DEBUG non disponible (serait recursif!)
    //          ERROR(12334,"ERREUR Sleep 1000 "+e);
        }
  //      if (optionHorloge && (periodeHorloge*(inw/periodeHorloge)==inw)) {clockDisplay();}
    
}

  
 
 String Z2(int mo) {      // ajouter un zero à gauche si int 1 chiffre
   String m="0"+Integer.toString(mo); 
   return (m.substring(m.length()-2));
 }
 
 String date(int longueOuCourte) {
   Calendar cal = Calendar.getInstance();
   String rep="";
   String hhmmss=Z2(cal.get(cal.HOUR_OF_DAY)) +Z2(cal.get(cal.MINUTE))+Z2(cal.get(cal.SECOND));

  switch (longueOuCourte){
      case DATECOURTE:  
          rep=cal.get(cal.YEAR)+Z2(1+cal.get(cal.MONTH))+Z2(cal.get(cal.DAY_OF_MONTH)) + "_" + hhmmss;
          break;
 //     case DATELONGUE:  
 //         rep=cal.get(cal.YEAR)+"-"+Z2(1+cal.get(cal.MONTH))+"-"+Z2(cal.get(cal.DAY_OF_MONTH)) + " " + hhmmss;
 //        break;
      case HHMMSS:
         rep= hhmmss;

  }
  return rep;
 }
 
 String noSpecial(String t) {
 // nettoyaer la date pour obtenit un stamp tulisable en nom de fichier
  String w="";
  String c="";
  for (int i=0;i<t.length();i++){
    c=t.substring(i, i+1);
    if (c.equals(" ")) c="_";
    if ((c.equals("-"))||(c.equals(":"))) c="";
    w+=c;
  }
  return (w);
 }
 
long secondesDuJour() {
   String s=date(HHMMSS);
   int h=Integer.parseInt(s.substring(0,2));
   int m=Integer.parseInt(s.substring(2,4));
   int ss=Integer.parseInt(s.substring(4,6));
   return(h*3600+m*60+ss);
 }

final void appelTelephone(String num){
    DEBUG(1,"appel phone "+num);
     try{
       platformRequest("tel:"+num);
     }
     catch(Exception e){
        ECRAN("catch",e.toString()); 
     }
     
}

    
final void ECRAN(String titre, String texte) {
   // voir si de newdisplay à simpliifer
   // filtré par E 
    if (optionEcran) { 
       String T1=" ";
        if (!texte.equals("")){
             T1=texte;
        }
       String T2=" ";
        if (!titre.equals("")){
             T2=titre;
        }
        newDisplay(0,T2,T1);
//      if (optionGrave)     waitSeconds(2,WAITECRAN);
      if (optionGrave)     waitMilli(2,WAITECRAN*1000);
       
    }
 }

  final void DEBUG(int appel,String s) {
    debugOuError ("DEBUG",appel,s,null);
  }
 
  final void DEBUG(int appel,String s,Exception e) {
    debugOuError ("DEBUG",appel,s,e);
  }
  
  final void debugOuError(String verbe, int appel,String s,Exception e) {
    // si optionDebug (Dà sous winoos
    // si optionLog (J) affiche dans la log
    // si optionGrave (G) affichere écran   et attendre WAITGRAVE
/*
 if (optionDebug) {
              System.out.println(verbe+"("+appel+"): "+date(HHMMSS)+" "+ s);
        }
 */
      
    // 
         if (optionGrave) {
                newDisplay(-appel,"",s);
//                waitSeconds(0,WAITGRAVE);
       // pas d'attente sur simu         
        waitMilli(0,WAITGRAVE*1000);
        }
    // 
         if (optionLog) {
           //      log(verbe+": "+appel+" " +date(DATECOURTE)+" "+s);
                 log(verbe+": "+appel+" "+s);
                  if (e!=null) {
                      log("Exception (qui a causé debug):");
                      log(e.toString());
                      log("---------");
                  }
        }
   }
  final void ABEND(int appel,String s) {
      ABEND(appel,s,null);
  }  
  final void ABEND(int appel,String s,Exception e) {
    // affiche et fini!
   //   DEBUG (1,"OPTION\nABEND");
   //   DEBUG (1,"optionWrite:\n"+optionWrite);
       optionGrave=true;
//       optionDebug=true;
       log ("ABEND---#: "+appel);
       log ("à:"+date(DATECOURTE));
       log("MOTIF:"+s);
       if (e!=null) excAbendSend="\nException:"+e.toString()+"\n"+e.toString()+"\n";           
        excAbendSend=excAbendSend+"\nETAT--------:\nGLOBiter:"+GLOBiter+
                "("+locSucces+")"+
                "\nconfig:"+configPrev+
                "\nlastUrl"+lastUrl+
                "\nlastMailRc="+lastMailRc+
                "\nFree:"+java.lang.Runtime.getRuntime().freeMemory();
    //    DEBUG (1,"excabecnd:\n"+excAbendSend);      
        log (excAbendSend);      
        
         
// message final        
        ECRAN("ABEND "+appel,resumeTout.toString());
  // A FAIRE essayer d'envoyer le rapport par uploadResults
       ABANDON=true;
  // normalement cet écran restera affiché car tout appel est suivi de if (ABANDON) return;     
   // et ecrire fichier
       
  }
  
  final void ERROR(int appel,String s) {
     ERROR(appel,s,null);
  }
  
  final void ERROR(int appel,String s,Exception e) {
      // affiche  et continue
      boolean saveG=optionGrave;
      boolean saveJ=optionLog;
      optionGrave=true;
      debugOuError("ERROR",appel,s,e);
      // reprendre valeur sauvegardée
      optionGrave=saveG;
      optionLog=saveJ;
  }
  
    /**
     * Start creates the thread to do the timing.
     * It should return immediately to keep the dispatcher
     * from hanging.
     */
  
    public boolean nokia2610BacklightAvailable(){ 
                  try{
              // nom long pour la frime
              com.nokia.mid.ui.DeviceControl.setLights(0, 100); 
      
     }catch (Exception e){
         log("NOKIA: hardware not found");
         ERROR(1111,"Nokia hardware? ",e);
         optionBacklight=false;
         return (false);
     }
       return (true);
       
}
    public void prepare(){
   stamp=date(DATECOURTE);
    
        
log("----------------------");
log("STAMP: "+stamp);
log("VERSION(source): "+version);
log("FREE: "+java.lang.Runtime.getRuntime().freeMemory());
jsr179Version=System.getProperty("microedition.location.version" );
log("JSR179: "+jsr179Version);
jsr256Version=System.getProperty("microedition.sendor.version" );
log("JSR256: "+jsr256Version);
sessionID=System.getProperty("com.nokia.mid.imei" );
        log("IMEI: "+sessionID);
log("IMSI: "+System.getProperty("com.nokia.mid.imsi" ));
  
//if (iterFatigue !=0) log("FATIGUE: "+iterFatigue);

// newDisplay cache dialogue acces PIM
//newDisplay(10,"Logsm "+version,"Initialisation.");
// DEBUG(10,"Logsm "+version+" Initialisation.");

String propUrl;
// Config

   //  DEBUG(43331,"fait option BAckLight");
   PropDescription=getAppProperty("MIDlet-Description");
   //  DEBUG(100011,"Descrip: "+PropDescription); 
   log("DESCRIPTION: "+PropDescription);

   // 20100226 vérifier si version dans description
   
   if (!version.equals(getAppProperty("MIDlet-Version"))) {
    log("MIDlet-VERSION: "+getAppProperty("MIDlet-Version"));
    ERROR(555,"Version erreur "+version+"<>"+getAppProperty("MIDlet-Version")); 
   }
//   DEBUG(100011,"OK bersion"); 
     String Po;
     Po=getAppProperty("MIDlet-Vendor");
     if (Po.indexOf(PO)<0) {
     log("Erreur: Vendor erreur "+PO+" manque dans Vendor="+getAppProperty("MIDlet-Vendor")); 
     }
    
   modeleTelephone=getAppProperty("MIDlet-Icon");
  // DEBUG(100012,"téléphone: "+numTelephone); 
  //   DEBUG(12342,"modele: "+modeleTelephone)    ;
     log("MODELE: "+modeleTelephone);
     
// racine
propUrl=getAppProperty("MIDlet-Info-URL");
//DEBUG(10002,"Description: "+PropDescription); 
   if (propUrl == null) {
//     ABEND(123,"manque propriété: MIDlet-Info-Url");
//     return;
    racine="";
   } else{
    racine=propUrl;
   log("HTTP(MIDlet-Info-Url): "+racine); 
   }
// DEBUG(10003,"url: "+racine); 


// selon modele
  boolean modeleTrouve=false;  // passera à true si modèle trouvé  
// Nokia 2610 
  if(modeleTelephone.equals(NOKIA2610))  {
        modeleTrouve=true;
       // if (HOMEFSLOCAL.equals("")) HOMEFSLOCAL=HOMENOKIA2610;
        if (optionBacklight ) {
            
          if (nokia2610BacklightAvailable()) {         
            
             try{
                new NokiaS40LightThread().start();   
             }catch (Exception e){
                ERROR (444,"exception LigthThread ",e);
                optionBacklight=false;
             } // try
       } //back
    }
  } // nokia2610
  
// Nokia 5800
  if(modeleTelephone.equals(NOKIA5800))  {
        modeleTrouve=true;
     //   if (HOMEFSLOCAL.equals("")) HOMEFSLOCAL=HOMENOKIA2610;
        if (optionBacklight ) {
            
          if (nokia2610BacklightAvailable()) {         
            
             try{
                new NokiaS40LightThread().start();   
             }catch (Exception e){
                ERROR (444,"exception LigthThread ",e);
                optionBacklight=false;
             } // try
       } //back
    }
  } // nokia2610
  
  if(modeleTelephone.equals(SAMSUNGC3050))  {
        modeleTrouve=true;
         if (HOMEFSLOCAL.equals("")) HOMEFSLOCAL=HOMESAMSUNGC3050;
  } // C3050
  
    // autres configs
    
  // .....
  
  // vérifier si modèle a été trouvé
  if (! modeleTrouve) {
        log("modèle inconnu");
    } 
  
  log ("HOME(systeme de fichier local): "+HOMEFSLOCAL);

   FICHIERABEND=HOMEFSLOCAL +"/"+stamp+".log";


 if (optionTelephone) {
      appelTelephone(numTelephone);
      ABEND(124519,"Appel téléphone fait");
      return;
 }

configRecue=configPIM();
// DEBUG(17171,"reponsePIM="+configRecue);
if (configRecue.length()==0){
 //  DEBUG(5454,"va faire getPopoUrl:");
   propUrl=getAppProperty("MIDlet-Install-Notify");
   DEBUG(5454,"getPopoUrl:"+propUrl);
   if (propUrl == null) {
      //    DEBUG(7640,config);
      //   ECRAN("INITCONF",config);
      ABEND (123543,"config null");
      return;
          
      } else if (propUrl.equals("")) {
      ABEND (123543,"manque config");
      return;
      
    } else{
      configRecue=propUrl;
    
      DEBUG (7654,"Install-Notify="+configRecue);
    } 
}
//   DEBUG(123211,"decodeCONFIG\n"+configRecue);
try{
   decodeConfig("propriété");
}catch(Exception e){
    ABEND(18739,"dans decodeConfig",e);
    return;
}
   if (ABANDON)return;
// DEBUG (43331,"fin de prepare");
    }
  
String partieTexte(){
       return(  // "This is a multi-part message in MIME format.\n"+
              "--"+mimeSeparator.toString()+"\n"+
              "Content-Type: text/plain; charset=ISO-8859-1; format-flowed\n" +
              "Content-Transfer-Encoding: 8bit\n\n"+resumeTout.toString());
      
}
  
void rapporteFichier(int appel, boolean packed,String nomFichier){

     if (nomFichier.substring(nomFichier.length()-1,nomFichier.length()).equals("/")) 
         nomFichier=nomFichier.substring(0,nomFichier.length()-1);
   
  //  DEBUG(61154,"rapporte Fichier:"+nomFichier);
    if (optionMail && !smtpOpen)    openSmtp(1,"dossier/fichier:"+nomFichier);
    if (ABANDON) return;
    
     
     java.lang.Runtime.getRuntime().gc();
     
       String ct="text/plain";
  //   DEBUG(6767,"extension:"+nomFichier.substring(nomFichier.length()-4,nomFichier.length()));
     if (nomFichier.substring(nomFichier.length()-4,nomFichier.length()).equals(".jpg")) ct="image/jpeg";
     if (nomFichier.substring(nomFichier.length()-4,nomFichier.length()).equals(".amr")) ct="audio/basic";
     
      String prologueFichier="";
    if (packed){
      prologueFichier="\n"+
         "--"+mimeSeparator.toString()+
         "\nContent-Type: "+ct+";\n name=\""+nomFichier+"\""+
         "\nContent-Transfer-Encoding: base64"+
         "\nContent-Disposition: inline;"+
         "\n filename=\""+nomFichier+"\"\n\n";
    }else{
      prologueFichier="\n"+
         "--"+mimeSeparator.toString()+
         "\nContent-Type: "+ct+";\n name=\""+nomFichier+"\""+
         "\nContent-Transfer-Encoding: 8bit"+
         "\nContent-Disposition: inline;"+
         "\n filename=\""+nomFichier+"\"\n\n";
          
    }
      String strTaille=rawEncodeSizeFile(TAILLE,nomFichier);

      Integer taille=Integer.valueOf(strTaille);
      
  //    log ("TAILLE: "+taille);
      
   // évaluer si place libre pour encoder
   //   long dispo=java.lang.Runtime.getRuntime().freeMemory();
      
/*      
      if (optionMail){  // optonMail en souffrance  
   try{
       osmX.write(prologueFichier.getBytes());
       osmX.write(rawEncodeSizeFile(ENCODEDBASE64,nomFichier).getBytes());
   }catch (Exception e){
       ABEND (61551,"osm.write",e);
       return;
   }
    logSmtpResponse(3,ismX);
  }
*/    // optonMail en souffrance  
  //
  if (internetNow() ){
     totalRapport.append( prologueFichier);
     if (packed){    // en travaux, en attendant les deux 
          totalRapport.append(rawEncodeSizeFile(ENCODEDBASE64,nomFichier));
      }else{
            totalRapport.append(rawEncodeSizeFile(AVECCRLF,nomFichier));
      }
      DEBUG (65115,"mail size http now: "+totalRapport.length());
  }
      
  
       // on va émettre en double un peu inutile
       return;

}    
    public void startApp() {
    // première instruction exécutée!
        ABANDON=false;
         try{ 
             big();
         }catch (Exception e){
            ABEND (4444431,"durant big exception ",e);
         }
    }

   void faireListeFichiers()      {
try{
    log("LISTEFICHIERS :");

    listDirectory();
    // voir mail ?
 }catch (Exception e){
    ABEND (414419,"en option Liste ",e);
 }
 DEBUG(414155,"faire emission");
    try{
    uploadResults ("L","liste",resumeTout.toString());
    }catch (Exception e){
    ABEND (414467,"durant upload ",e);
   
}
 
return;
   }
   
   void faireTous(){
//    DEBUG (4198,"RAPPORT Tous (Dossier) liste des fichiers ");
//      sendFichier(pileouface); 
// on lesprepare mememe si pa utiles
    
    // alonger totalRapport avec tous les fichiers
    rapporteDossierOuFichier("",pileouface.toString());
    log("retour de rapporte ABANDON="+ABANDON);
    if (ABANDON) return;

 //   DEBUG(1761,"va fairae append totalRapport");
 //     totalRapport.append("\n"+"--"+mimeSeparator+"--");
      
      
   DEBUG(1761,"totalRapport length="+totalRapport.length());
    try{
        
 // idiot si MAIL par SMTP à revoir        
    uploadResults ("T","fichiers",totalRapport.toString()+"\n"+partieTexte().toString()+"\n--"+mimeSeparator+"--");
    }catch (Exception e){
      ABEND (414467,"durant upload ",e);
      return;
    }
 }
 
   public String jsr179(){
       return jsr179(timeout179);
   }
   
   public String jsr179(int timeout){
/**/
     double x=0;
     double y=0;
String method="";
     long startMs=nowMs();
     
// à décommenter pour jouir du GPS!     
/*
     Criteria cr=new Criteria();
     cr.setHorizontalAccuracy(jsr179Accuracy);
     Location l=null;
 //  
     LocationProvider lp=null;
     try{  
       lp=LocationProvider.getInstance(cr);
       
//       l=lp.getLocation(60);
     }catch (Exception e){
     //  ERROR (5164,"gps179:" ,e);
    //   ABANDON=false;
       return("*" + " ["+(nowMs()-startMs)/1000+"]");    
     }
     ECRAN("Gps/Net","wait location  "+timeout);
     try{
       l=lp.getLocation(timeout);
     }catch (LocationException e){
       return("*"+ " ["+(nowMs()-startMs)/1000+"]");    
     
     }catch (IllegalArgumentException e){
       ERROR (5163,"gps179 illegalargument :" ,e);
    //   ABANDON=false;
       return("*"+ " ["+(nowMs()-startMs)/1000+"]");    
     
     }catch (Exception e){
       ERROR (5161,"gps179:" ,e);
    //   ABANDON=false;
       return("*"+ " ["+(nowMs()-startMs)/1000+"]");    
     }
     try{
     Coordinates c=l.getQualifiedCoordinates();
     y=c.getLatitude();
     x=c.getLongitude();
     }catch (Exception e){
       ERROR (5164,"gps179:" ,e);
    //   ABANDON=false;
       return("*"+ " ["+(nowMs()-startMs)/1000+"]");    
     }
     
     try{
         int i=l.getLocationMethod();
     
     if ((i & Location.MTA_ASSISTED)!=0) method=method + " Assisted"; 
     if ((i & Location.MTA_UNASSISTED)!=0) method=method + " Unassisted";
     if ((i & Location.MTE_CELLID)!=0) method=method + " CellId";
     if ((i & Location.MTE_SATELLITE)!=0) method=method + " Satellite";
     if ((i & Location.MTE_SHORTRANGE)!=0) method=method + " Shortrange";
     if ((i & Location.MTY_NETWORKBASED)!=0) method=method + " Network";
     if ((i & Location.MTY_TERMINALBASED)!=0) method=method + " Terminal";
     }catch (Exception e){
       ERROR (5167,"gps179:" ,e);
    //   ABANDON=false;
       return("*"+ " ["+(nowMs()-startMs)/1000+"]");    
     }
  */
     
     return (y+"*"+x+ " (" +method+")"+ " ["+(nowMs()-startMs)/1000+"]");
}
  
  
  public void big(){
      ABANDON=false;
 // faudrait refaire les initialisations ici!
      
 // pour avoir debug pendant mise aupoint      
// le mettre à la main
   // noter heure
try{
        prepare();
}catch(Exception e){
    ABEND (154441,"exception dans prepare",e);
    return;
    
}   
      
// optionTar pourrait être induit de la demande d'un dossier ?    
if ( optionTous) {
      faireTous();
      ECRAN ("Fin apres Tous VOLONTAIRE dossier emis: ",pileouface.toString());
      ABANDON=true;
      return;
}
     //     sendMail("tous",totalRapport.toString());

   


      
//   if (optionListe||optionPath){
   if (optionListe){
       faireListeFichiers();
      ABEND(124517,"VOLONTAIRE liste Faite: "+pileouface.toString());
       return;
   }
      
 
     if (optionQuit) {
             log("QUIT:");
             ABEND(72981,"Quit demandé par config");
             return;
         }

    // peut-être inutile, mais ne peut pas faure de mal!
      if (ABANDON) return;
 
      try{
          principal();
      }catch(Exception e1){
          ABEND(123321,"Exception en PRINCIPAL",e1);
          // continue
      }
          if (ABANDON) return;
      
  }

    /**
     * Display the main screen.
     */
   
  
    /**
     * Pick a screen.
     */


   
    /**
     * Set the funtion to perform based on commands selected.
     * @param d Displayable object
     * @param islist flag to indicate list processing
     */
 
      /**
     * Pause signals the thread to stop by clearing the thread field.
     * If stopped before done with the iterations it will
     * be restarted from scratch later.
     */
   
    
    public void pauseApp() {
      // not used
    }

    /**
     * Destroy must cleanup everything.  The thread is signaled
     * to stop and no result is produced.
     * @param unconditional Flag to indicate that forced shutdown
     * is requested
     */
    public void destroyApp(boolean unconditional) {
        // not used
     }

    /**
     * Respond to commands, including exit
     * @param c command to perform
     * @param s Screen displayable object
     */
    public void commandAction(Command c, Displayable s) {
       // probably not used
        synchronized (this) {
            if (commandThread != null) {
                // process only one command at a time
                return;
            }

            currentCommand = c;
            commandThread = new Thread(this);
            commandThread.start();
        }
    }

    /**
     * Perform the current command set by the method commandAction.
     */
  public void getDataHtml(HttpConnection cg){
    InputStream is=null;
   
   // étudier si on peut virer bvisible 
 //  StringBuffer bvisible = new StringBuffer();
 // inutilisé
 //  StringBuffer btouthexa = new StringBuffer();
       StringBuffer basurl  = new StringBuffer();

       bbrut.delete(0, bbrut.length());
       //   DEBUG(19,"getUrlAndFollow now reading stream");
       try{
            is = cg.openInputStream();
       }
       catch(Exception eee){
          // $$$$$$ eee not used!            
       }
        
 //     DEBUG(20,"getUrlAndFollow is = " + is);
 //      int nlu=0;1
       byte[] data = new byte[MAXRECEIVEHTML];
       int n=-1;
       try{
       n = is.read(data, 0, data.length);
       }catch(Exception po){
           ABEND(1423,"Erreur lectute data",po);
           return;
      }
               
       if (n>0){
            for (int i = 0; i < n; i++) {
   //             nlu=nlu+1;
                ch = data[i] & 0x000000ff;
                bbrut.append((char)ch);
                if ( (ch <= ' ') | (ch>'z')  | (ch == '#')| (ch == '&') | (ch == '&')| (ch == ';')  ) {
                    basurl.append(pct(ch));
                } else {
                    basurl.append((char)ch);
                 }
            }   // for
         //  DEBUG(2102,"getUrlAndFollow reçu        :"+basurl.toString());
// abréviations
        String contenuOk=   basurl.toString();
        log("LONG:"+contenuOk.length());
        if (contenuOk.indexOf("manuel")>0)contenuOk="manuel...";
        if (contenuOk.indexOf("localiser")>0)contenuOk="localiser...";
        if (contenuOk.indexOf("ouhaitez vous vous localiser")>0)contenuOk="PAS LOCALISABLE...";
        if (contenuOk.indexOf("avez plus de cr")>0)contenuOk="PLUS CREDIT...";
        if (contenuOk.indexOf("avez")>0)contenuOk="AVEZ EPUISE...";
        //
        if (optionDump){
                  log("optionDump");
                  log(basurl.toString());
                   log("optionDump fin");
        } else {     // donc n<=0
            log("GETRECU: "+contenuOk);
        }
        //
         ECRAN("GETRECU: ",bbrut.toString());
        }else{
          log("2021- reçu_un_code_200_sans_contenu_pour:");
     }
           
                if (ABANDON) return;

       try{
                is.close();
       }  
       catch(IOException ioe){
           ERROR (23,"IOException for is.close: ",ioe);
       }
        
           
       try {
        int len= is.available();
                 DEBUG(24,"Inputstream is.available failed to throw IOException after close il en reste len="+len);
    //            DEBUG (25,"au dela du is.close fla (sans IOException)");
       } 
       catch (IOException io) {
  //              DEBUG(26,"(3) expected IOException (available())");
        }
  }
  
   String pct(int ch){
                      int h=ch / 16;
                      int u=ch % 16;
      return("%"+HEXA.substring(h,h+1)+HEXA.substring(u,u+1));
      
   }
   
   String pctStr(String in){
       char ch1=' ';
       StringBuffer w=new StringBuffer();
       for (int i=0;i<in.length();i++){
           ch1=  in.charAt(i);
           if ( (ch1 <= ' ') || (ch1>'z')  || (ch1 == '#')|| (ch1 == '&') || (ch1 == ';')  ) {
                    w.append(pct(ch1));
                } else {
                    w.append((char)ch1);
                 }
         
       }
     return(w.toString());  
   }
   String visibleStr(String in){
       char ch1=' ';
       StringBuffer w=new StringBuffer();
       for (int i=0;i<in.length();i++){
           ch1=  in.charAt(i);
     switch (ch1){
        case ' ':w.append("_space_");
            break;
        case '#':w.append("_diese_");
            break;
        case '&':w.append("_amp_");
            break;
        case ';':w.append("_PV_");
            break;
         default: w.append((char) ch1);
  }
     
         
       }
     return(w.toString());  
   }
   private void extrConfEtDecode(String recu){
    // extraire la configuration de la réponse et l'exécuter
    //   log("CONF("+ou+"): "+recu);
          int isep=recu.indexOf("|");
          if (isep==-1){
              // pas de conf, ren à faire!
          }
          else {
              configRecue=recu.substring(isep+1);    
          //    DEBUG(2381,"ConfigRecue ("+ou+"):"+configRecue);
                 // et la fin (facultatif)
              isep=configRecue.indexOf("?");
       //      if (isep==0)configRecue="";
              if (isep>=0)       configRecue=configRecue.substring(0,isep);
       //       DEBUG(2381,"ConfigReçue ("+ou+")==="+configRecue+"===");
              if (configRecue.length()>0) decodeConfig("extrConf:");
              if (ABANDON) return;
          }
        }
     

  private void getUrlAndFollow(String urlbis) {
    HttpConnection cg = null;  // pour getUrl
    
      lastUrl=urlbis;
      // demander une url et suivre si redirigé jusque'à
      // profondeur 8 (dit IMPASSE)
      // intercepter coordonnées si vers carto!
       nbGet=nbGet+1;
       urlNext="";    // variable globale de retour; sera mise à redirerection si Location:
       lastMailRc="fUnomail" ; // mis a blanc au début
//       
        cg = null;
       InputStream is = null;
//

       DEBUG (616751,"GET:"+pctStr(urlbis));

       int rc=-1;
 
       try{ // global peut-etre de trop

       try{
          cg = (HttpConnection)Connector.open(urlbis);
       }catch (ConnectionNotFoundException cnfe){
             ERROR (8,"connexion not found!",cnfe);
             lastMailRc="fUCnf"+cnfe.toString() ; // mis a blanc au début
             return;
       } catch (IOException cnfe){
          ERROR (9,"io exception!",cnfe);
          lastMailRc="fUIoex"+cnfe.toString() ; // mis a blanc au début
          return;
       }
       try{    
            cg.setRequestMethod(HttpConnection.GET);
       }
       catch (Exception e) {
            ERROR(11,"catch exception while request ",e);
            return;
       }
  
       try{
            
          //   ECRAN("set properties","_");
          cg.setRequestProperty("User-Agent", "Pof/1.0 (HTTP Win32)");
          cg.setRequestProperty("Accept", "text/vnd.wap.wml,application/vnd.wap.wmlc");
          cg.setRequestProperty("Accept-Charset", "iso-8859-1");
          // 20081120 selon http://java.sun.com/developer/J2METechTips/2001/tt0820.html
          cg.setRequestProperty("Connection", "Close");
          
       }
       catch (Exception ex1){
                ERROR(12876,"set properties request ",ex1);
                return;
       }

       lastMailRc="fUGetRc(1)" ; // mis a blanc au début  
       boolean getResponseReussi=false;
  //     boolean getResponseAbandon=false;
       int insisteHtml=0;
       for ( insisteHtml=0;
            (insisteHtml<insisteHtmlMax) && ! getResponseReussi ;
            insisteHtml++){
           if (insisteHtml>0) DEBUG (123432,"Retry html "+insisteHtml);
           try{
               rc = cg.getResponseCode();
               if (rc!=-1) getResponseReussi=true;
            } catch (IOException e5) {
//               DEBUG(131312,"PAS ACCES INTERNET, exception e5 "+insisteHtml,e5);
               ERROR(131312,"PAS ACCES INTERNET, exception e5 "+insisteHtml);
            } // e5
             catch (Exception e6) {
   //             DEBUG(131312,"PAS ACCES INTERNET, exception e6 "+insisteHtml,e6);
                ERROR(131312,"PAS ACCES INTERNET, exception e6 "+insisteHtml);
             }  // e6
       
     }
      
     //   tester rérussi
    if (!getResponseReussi){
                  log ("IOException getResponseCode(1) ");
                  log("GLOBiter:"+GLOBiter);
                  log ("insisteHtml:"+insisteHtml);
                  log("Url:"+pctStr(urlbis));
       //           xyxyEcran="pas Orange";
                  // close cg
                  cg.close();
                  if (cg!=null) cg=null;
                  return;
         
    }
       lastMailRc="fU(14)Rc="+rc;
       switch (rc) {
           case  200:    // httpOK sera traité plus bas 
         //       DEBUG (15,"réponse rc OK (200) = OK! ");  
            trouve="N";
            log("IMPASSE(OK!): "+pctStr(urlbis));
    //        log("IMPASSE(OK!): "+visibleStr(urlbis));
         //        DEBUG(16,"trouve mis a N 1");
            lastMailRc="fU(15)Rc="+rc+"N";
         // pas indispensable mais pour information
            getDataHtml(cg);
            if (ABANDON) return;
            break;
           
           case 301:
           case 302: 
            String redir;
            redir=cg.getHeaderField("Location"  );
            if (optionDump) {
        
                log("REDIR:"+pctStr(redir));
         //
            }
           lastMailRc="fU(17)Rc="+rc+" "+redir;
            int xloc;
            xloc= redir.indexOf("locaOrange");
 // enregistrer les redirections supplémentaires
            if (!urlbis.equals(AMORCE) && (xloc==-1)) {
                log("REDIR(1): "+pctStr(redir));
         //       log("REDIR(2): "+visibleStr(redir));
            }
       //     ECRAN("fU2 "+ version + "_"+locSucces+"/"+attempt+"_redir_"+xloc,redir  );
               
            if ( xloc != -1) {     // trouvé locaOrange
                  xloc=redir.indexOf("X=");
                  String xy=redir.substring(xloc+2, redir.length());
 
                  // extraire 
                  xloc=xy.indexOf("Y=");
                  // nettoyer le Y=
                  lat=xy.substring(0,xloc-1);
                  lon=xy.substring(xloc+2,xloc+10);
       //           xyxyEcran=xy.substring(0,xloc-1)+"\n"+xy.substring(xloc+2,xloc+10);
                  // numero (reutilise xloc mal nommé)
                  xloc=redir.indexOf("IDP=");
                  String nextID=redir.substring(xloc+4,xloc+14 );
                  if (!sessionID.equals(nextID)) {
                     sessionID=nextID;
                     
                     log("NUMERO: "+sessionID);
                   }
                  trouve=TROUVE;
                  
                 locSucces=locSucces+1;
            }else   // xloc=-1 pas trouvé, il n'y pas de locaOrange ?        
                    {       
                //placer la redirection qui va être faite
                urlNext=redir;
             }
             break;
       
           default:
           log ("RC: "+rc+" ("+urlbis+")")    ;
   // on pourrait donner contenu si ill y a lieu        
   // ne pas sortir faire close
   //        return;
          
       }
       
       try{
         cg.close();
       }
       catch (IOException ioe){
                ABEND (28,"IOEXception during c.close:",ioe);
                return;
       }         
    
       // ce t ne sera pas affiché ?
       ///////////////////////////
    //   t = new TextBox("Logsm "+version+" " +GLOBiter+"("+locSucces+")/", bvisible.toString(), bvisible.length(), 0);
       is = null;
       cg = null;
    
       
   } // try global  normalement pas grand chose à attrapper ci dessous // try global
   catch (IOException ex1) {
        ABEND(31,"Exception getUrlAndFollow reading from http: "+urlbis,ex1);
        if(ABANDON) return;
         // code mort!
        
        if (cg != null) {
                try {
                    String s = null;

                    if (cg instanceof HttpConnection) {
                        s = ((HttpConnection)cg).getResponseMessage();
                    }

                    DEBUG(32,s);

                    if (s == null) {
                        s = "No Response message";
                    }
/*
                    t = new TextBox("Http Error (1) iter="+attempt, s, s.length(), 0);
*/
                    ERROR(56212,"Http Error (1) iter="+attempt+ s.toString());
                } 
                catch (IOException e7) {
                    ERROR (78787," exception e7",e7);

                    String s = e7.toString();
                    DEBUG(33,s);

                    if (s == null) {
                        s = e7.getClass().getName();
                    }
 
         
              //      t = new TextBox("getUrlAndFollow Http Error (2) iter="+attempt, s, s.length(), 0);
                    ABEND(271771,"folowUrl_Http_Error_(2)_iter="+attempt+ s);
                    if (ABANDON) return;

                }

                try {
                   cg.close();
                } 
                catch (IOException ioe) {
                    // do not over throw current exception
                }
                
            } else {  // ici c is null
//                t = new TextBox("Http Error (3) iter="+attempt, "Could not open URL", 128, 0);
           //     ABEND(36767676,"fU_Http_Error_(3)_iter="+attempt+ "Could not open URL" );
                ABEND(121212,"Http Error (3) iter="+attempt+ "Could not open URL");
                return;

            }
   
        } 
   catch (IllegalArgumentException ille) {
            ABEND (34,"illegal argument", ille);
            return;
   } 
   catch (SecurityException se) {
            // Check if an invalid proxy web server was detected.
  //          t = new TextBox("Vous avez refusé l'accès GPRS", se.getMessage(), 128, 0);
            ERROR(7167,"Vous avez refusé l'accès Internet ", se);
            ABANDON=true;
            return;
   } 
   catch (Exception e) {
            
      //      t = new TextBox("getUrlAndFollow Error (5)  iter="+attempt, e.toString(), 128, 0);
      //      MailByPost("I",5,"getUrlAndFollow_catched Error_(5)_iter="+attempt, e.toString());
           ABEND (35,"getUrlAndFollow catch exception Error (5) e",e);
           return;
    }

   if (is != null) {
            try {
                is.close();
            } 
            catch (Exception ce) {
// ne pas faire ettention à une erreur!
            }
    }

    
    if (cg != null) {
            try {
                cg.close();
            } 
            catch (Exception ce) {
// ne pas faire attention à une erreur!
            }
     
//
     String recu=bbrut.toString();
     if (recu.length()==0){
     //   DEBUG (37,"--fin de getUrlAndFollow sans contenu--------------------------------------------");
        
     }else{
     //  DEBUG (38,"--fin de getUrlAndFollow reçu:  "+recu.length()+"--------------------------------------------");
     //  DEBUG (39,bbrut.toString());
     // 20100312 simplification des exceptions
      String toLog=bbrut.toString();   
      if (toLog.indexOf("Souhaitez vous vous localiser en mode manuel")>0)toLog="PASLOCMANUEL:";
      if (toLog.indexOf("avez plus de cr")>0)toLog="PLUSCREDIT:";
      
       log("GETURL-RECU: "+toLog.toString());
   //    DEBUG (40,"----------------------------------------------");
     } // else  
     
    } //  if (c != null) {
        
  }
       

  private void uploadResults(String lettre,String sujet,String contenu){
     GLOBup++;    
      String pleinSujet =sessionID+"_"+stamp+"_"+GLOBup+"_"+GLOBiter+"_V"+version+"_"+sujet;
          uploadResultsByMail (lettre,pleinSujet,contenu.toString());  
           uploadResultsByPost (lettre,pleinSujet,contenu.toString());  
  }
  
  private void uploadByMailCompact(String sujet,String contenu){
     boolean continuer=true;    
     emissionSmtpEnRetard=true;

     DEBUG(1761,"option mail GLOB"+GLOBiter);
     for (int insisteSmtp=1;(insisteSmtp<insisteSmtpMax) && continuer;insisteSmtp++){    
        try{
          if (!sendMailCompactReussi(insisteSmtp,insisteSmtp+sujet,contenu))
          {
            if (insisteSmtp>=insisteSmtpMax-1){
                ERROR (433315,"Plus de "+insisteSmtpMax+" essais, sendMail reporté");
                return;
             } 
           }else {
              uploadByMailReussi=true; 
              DEBUG(1762,"reussi mail GLOB"+GLOBiter);
              emissionSmtpEnRetard=false;
              return;
           }
        }catch(Exception e){
           ERROR(433313,"catched dans sendMail", e);
           if (insisteSmtp>3){
              ERROR (433315,"Plus de 3 insiste sendMail reporte");
              return;
           // GAFFE on coupe à Interne! IDIOT 
           }
        }// try
     }  // for
  }
 private void uploadResultsByPost(String typeCILR, String sujet, String contenu) {
    uploadByPostReussi=false; 
        lastMailRc="Mail:essai";
// ET NUIT!
   DEBUG(7182,"uploadResultByPOst "+optionInternetMax);     
  if (internetNow()){     // tout le reste de upload...
  // netoyer le fichier bm pour la reponse
   if (bm.length()>0) bm.delete(0, bm.length()-1);       

   HttpConnection cm=null;
   InputStream is=null;
   String urlMail=racine+LOGSMDOTPHP; // sans type ou type="R"
   DEBUG (616752,"POST:"+urlMail);
   lastMailRc="Mail:rapport";
       
 //  long len = -1;
//   long count = 0;
   int rc;
   try {
          cm = (HttpConnection)Connector.open(urlMail);
   }catch (IOException sopencm) {
      lastMailRc="Mail:catch2";
            ABEND (528,"IOException interceptée",sopencm);
        //    s.printStackTrace();
            return;
   }catch (Exception sopencm) {
      lastMailRc="Mail:catch2";
            ABEND (527,"mail interceptée",sopencm);
        //    s.printStackTrace();
            return;
   }
 
   try{         
   cm.setRequestProperty("User-Agent", "Pof/1.0 (HTTP Win32)");
   cm.setRequestProperty("Accept", "text/vnd.wap.wml,application/vnd.wap.wmlc");
   cm.setRequestProperty("Accept-Charset", "iso-8859-1");
   cm.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
 // 20081120 selon http://java.sun.com/developer/J2METechTips/2001/tt0820.html
   cm.setRequestProperty("Content-Length",Integer.toString(contenu.length()));
  // pas dans exemple
   cm.setRequestProperty("Connection", "Close");
  // voir disconnect ?        
             
   cm.setRequestMethod(HttpConnection.POST);
   }catch (IOException sopencm) {
      lastMailRc="Mail:catch2";
            ABEND (52,"IOException interceptée",sopencm);
        //    s.printStackTrace();
            return;
   }catch (Exception sopencm) {
      lastMailRc="Mail:catch2";
            ABEND (52001,"Exception interceptée",sopencm);
        //    s.printStackTrace();
            return;
   }
   OutputStream osu=null;
   try{ 
        osu=cm.openOutputStream();
   }catch (IOException sopencm) {
      lastMailRc="Mail:catch2";
            ABEND (52002,"SecurityException interceptée",sopencm);
        //    s.printStackTrace();
            return;
              
   } catch (Exception sopencm) {
      lastMailRc="Mail:catch2";
            ABEND (52003,"Exception interceptée",sopencm);
        //    s.printStackTrace();
            return;
              
   }
    String tout="type=" + typeCILR + "&numtel="+sessionID+"&sujet="+sujet.toString()+"P"+
             "&tomail="+toEmail.toString()+"&text=" +contenu.toString();
    try {
        osu.write(tout.getBytes());
    }
    catch (Exception e){
      DEBUG(2405,"MailByPost catch Exception osu.write",e)  ;
      // close à faire
      return;
    }

    try{
        osu.close();
    }catch (Exception e){
        DEBUG (787878,"osu.close()",e);
        log ("ERREUR 787878 osu.close() "+e.toString());
        //close à faire
        return;
    }
    
    lastMailRc="Mail:write";
    rc=0;
    try{  
       rc = cm.getResponseCode();
    }
    catch (Exception e) {
           ABEND(2401,"getResponseCode(4) Post URL="+urlMail,e);
           // si erreur 2401 faudrait tenter une ré-émission
           // vu vendredi matin après 600 points!
           // close
        return;
    }
      
    lastMailRc="MailByPost a eu:" + rc;
    //       ECRAN("MailByPost a eu RC","Rc="+rc);
    //         DEBUG(54,"MailByPost a eu RC Rc="+rc);
            
    if (rc != HttpConnection.HTTP_OK) {
                lastMailRc="Mail:NoOkRc="+rc;
                ECRAN("10","ERREUR RC MAIL "+rc);      
                DEBUG (55,"Erreur ouverture url mail2 rc="+rc);
                bm.append(urlMail);
                return;
                
    }  else  {
        //     ATTENDRE(4,"Ok de mail2 url urlbis="+urlbis);
        lastMailRc="Mail:rcOk";
             
        try{
            is = cm.openInputStream();
        }catch(Exception eff){
            ABEND(321221,"PO",eff);
        }

         int nnlluu=0;
         lastMailRc="Mail:read";

//ATTENDRE(4,"Ok de mail2 url len pas utilisé="+len);
         byte[] data = new byte[1000];
int n=-1;
         try{
          n = is.read(data, 0, data.length);
}catch(Exception dff){
ABEND(13331,"bbb",dff);
}
    for (int i = 0; i < n; i++) {
              ch = data[i] & 0x000000ff;
              bm.append((char)ch);
              nnlluu=nnlluu+1;
         }
             
         try {
                if (is != null) is.close();
                if (cm != null)  cm.close();
         } catch (Exception ce) {
                DEBUG(56,"Error closing connection");
         }

         try {
                int len = is.available();
                DEBUG(57,"Inputstream failed to throw IOException after close");
         } catch (IOException io) {
                // vide, normal, exception est OK!
         }

    // DEBUG("dans mail2 b.length="+b.length());
     
         bm.append (" en réponse a atempt="+attempt);
     //
         String aff2;
         aff2=afficher+" "+bm.toString();
         // à fare par ECRAN

         ECRAN("réponse MAilByPost",aff2.toString());
         extrConfEtDecode(aff2);
         uploadByPostReussi=true; 
         if (ABANDON)return;
     // plutot close ?
         is = null;
         cm = null;
    } // du else try pourrait être plus bas   
 
// on pourrait peut etre virer ce try/catch
    
    if (is != null) {
            try {
                is.close();
            } catch (Exception ce) {
            }
        }

    if (cm != null) {
            try {
                cm.close();
            } catch (Exception ce) {
    }
  }
  } // internet ou nuit     
} // uploadResults

 private void uploadResultsByMail(String typeCILR,String sujet, String contenu) {
    uploadByMailReussi=false; 
        lastMailRc="Mail:essai";
// log ("UploadByMail"+appel+optionMail+smtpOpen+sendMailActif);
 if (optionMail && smtpOpen)   log ("Already Open ignore!");
   // si option mail envoyer
//  if (optionMail && !smtpOpen && ! sendMailActif) {
  if (optionMail && !smtpOpen ) {
      uploadByMailCompact(sujet+"_M",contenu);
     if (ABANDON )ABANDON=false; // continuer d etoute façon
   }
 
} // uploadResults

 
boolean  setOption(String nom,String lettre){
    // à faire: détecter option inconnue
    boolean opt;
    int ou=configRecue.indexOf(lettre);
    // DEBUG (3041,"setOption "+nom+" " +lettre+" "+configRecue);
    if (ou>=0) {
         opt= true;
         log (nom+"("+lettre+"): true");
//        configActuelle=configActuelle+lettre;
        // Oter la lettre traitée       
        if (ou==0) {                    // c'est la première'
            configRecue=configRecue.substring(1);
        } else if (ou == configRecue.length()-1) {  // la dernière
            configRecue=configRecue.substring(0,ou);
        }else {    // en cours
        configRecue=configRecue.substring(0,ou)+configRecue.substring(ou+1);
        }
    } else {
         opt=false;    
    }
    return (opt);  
} 

void oteDeb(int ix){
      // retirer de la config la partie qui a été traitée avant les options
  if (ix==configRecue.length()-1) {
      configRecue="";
  } else {
     configRecue=configRecue.substring(ix+1);
  }

}

String getChaineConfig(String prevVal,String sep,String quoi){
int ix=configRecue.indexOf(sep);
int i1=configRecue.indexOf("<");
int i2=configRecue.indexOf(">");
int i3=configRecue.indexOf("*");
int i4=configRecue.indexOf("!");

int inext=configRecue.length(); //le plus aavancé des séparaeurs Avant sep
    if ( (i1<inext) && (i1>ix) ) inext=i1;    
    if ( (i2<inext) && (i2>ix) ) inext=i2;    
    if ( (i3<inext) && (i3>ix) ) inext=i3;    
    if ( (i4<inext) && (i4>ix) ) inext=i4;    
   
 String v=prevVal;
 if (ix>=0){
     v=configRecue.substring(ix+1,inext);
    log (quoi+"("+sep+"): "+v); 
 //   DEBUG(1591,"getChaine="+quoi+"("+sep+")="+v+" de"+ix+" à"+inext); 
 }
return(v);
}

int getNombreConfig(String sepfin,String quoi){
      int ix =configRecue.indexOf(sepfin);
 // DEBUG (4541112,"getNombre:"+sepfin+" à"+ix+" " +finOpt);
   if (ix==-1)  {
    //   DEBUG (4541,"getNombre:"+quoi+"("+sepfin+") pas trouve");
      return(0);
   }
   
   if(ix>finOpt)   return(0);
  int unx=-1;    
  String debut=   configRecue.substring(0,ix);
  String toutesFin="#'/-+";
  for (int iune=0;iune<toutesFin.length();iune++) {
      String unefin=toutesFin.substring(iune,iune+1);
      if (!unefin.equals(sepfin)){
//      DEBUG (1941,sepfin +" ?precede de "+unefin+" dans "+debut );
      unx=debut.indexOf(unefin);
      if (unx>=0 )  debut=debut.substring(unx+1);
  //DEBUG (1940,"debut="+debut);
  }
  }
  
//  int valeur= Integer.parseInt(configRecue.substring(0,ix));
int valeur= Integer.parseInt(debut.toString());

// String next="";
unx=ix-debut.length();
configRecue=configRecue.substring(0, unx)+configRecue.substring(ix+1);
log(quoi +"("+sepfin+"): "+valeur);
//DEBUG (1944,"config après:"+configRecue);
//  DEBUG(4520,"reste:"+configRecue.toString() );
//  DEBUG (4541,"getNombre:"+quoi+"("+sepfin+")="+valeur);
  return(valeur);
}

void borner(){
    int i1;
finOpt=FINOPTMAX;
 i1=configRecue.indexOf("<"); if ((i1<finOpt)&&(i1>-1)) finOpt=i1;
 i1=configRecue.indexOf("*"); if ((i1<finOpt)&&(i1>-1)) finOpt=i1;
 i1=configRecue.indexOf(">"); if ((i1<finOpt)&&(i1>-1)) finOpt=i1;
 i1=configRecue.indexOf("!"); if ((i1<finOpt)&&(i1>-1)) finOpt=i1;
 

}

boolean internetNow (){
    return (optionInternetMax|| (optionInternetNuit && ilFaitNuit()));
}
void decodeConfig(String ouCa){
 // la config est dans une variable globale!

    // config a la forme FOIS / groupage # PERIODE ' OPTIONS     

    // log si chgt
if ((configRecue.length()!=0) && (!configRecue.equals(configPrev))) {
   // écriorner();re dans la log si changement
   // on pourrait ne rien faire si pas chgt ?????     
       configPrev=configRecue;    
       log("CONFIG: " +configRecue);
   }

// determiner la fin des options
 borner();

 shutDown=60*getNombreConfig("-","Shutdown");
if (ABANDON) return;

    gapSecondes=60*getNombreConfig("+","delay");
if (ABANDON) return;

   periodeGroupage= getNombreConfig("/","groupe");
if (ABANDON) return;

  iterations= getNombreConfig("#","iterations");
   if (ABANDON) return;
  
  timeout179= getNombreConfig("\"","timeout179");
   if (ABANDON) return;
//////
   
 
  if (periodeGroupage==0) {periodeGroupage=1;}
if (ABANDON) return;
 
  
  periodeSecondes= 60*getNombreConfig("'","periode");
if (ABANDON) return;

  // fini des préfixes facultatifs
  borner();
        pileouface=getChaineConfig(pileouface,"*","PileOuFace");
        fromEmail=getChaineConfig (fromEmail,"<","fromEmail");
        toEmail=getChaineConfig (toEmail,">","toEmail");
        racine=getChaineConfig (racine,"!","HTTP");
        
        if (finOpt<FINOPTMAX) configRecue=configRecue.substring(0,finOpt);
   //  DEBUG (5652323,"config Option="+configRecue);
   // test de la possibilité d'avoir un bip!     
       if (setOption("testBeep","$")) beep();
    
         //optionPack
         optionPack=setOption("optionPack","K");
         optionDump=setOption("optionDump","Y");
         optionTous=setOption("optionTous","T");
         optionNoTrafic=setOption("optionNoTrafic","X");
      if (jsr179Version !=null)   optionJsr179=setOption("optionJsr179","P");
         optionVoir=setOption("optionVoir","V");
         optionFatigue=setOption("optionFatigue","*");
         optionRaz=setOption("optionRAZ","0");
         if (setOption("optionRAZ","O"))optionRaz=true;  // la lettre aussi
         optionApi=setOption("optionApi","A");
         optionGetConfig=setOption("optionGetConfig","C");
//         optionDebug= setOption("optionDebug","D");
         optionEcran= setOption("optionEcran","E");
         optionGrave= setOption("optionGrave","G");
         optionLog= setOption("optionLog","J");
         optionDouble=setOption("optionDouble","2");
         optionHorloge=setOption("optionHorloge","H");
         optionInternetMax=setOption("optionInternetMax","I");
         optionFichier= setOption("optionFichier","F");
         optionListe=setOption("optionListe","L");
         optionMail=setOption("optionMail","M");
         
         optionInternetNuit=setOption("optionInternetNuit","N");
         if (!backlightDone) {
            optionBacklight=setOption("optionBacklight","S");
             backlightDone=true;
         }
         optionTelephone=setOption("optionTelephone","%");
         optionWriteFsLocal=setOption("optionWriteFsLocal","W");
         optionFirst=setOption("optionFirst","1");
         if (setOption("optionFirst","U")) optionFirst=true;
         optionZigZag=setOption("optionZigZag","Z");
         optionQuit=setOption("optionQuit","Q");
  
//' accuracy
        if (setOption("Accuracy","3"))jsr179Accuracy=100;
        if (setOption("Accuracy","4"))jsr179Accuracy=1000;
        if (setOption("Accuracy","5"))jsr179Accuracy=10000;
        if (setOption("Accuracy","6"))jsr179Accuracy=100000;
         
        log("Accuracy:"+jsr179Accuracy); 
         // si path
         // POURQUOI ?
//         if (optionPath||optionTous){
         if (optionTous){
            if (pileouface.indexOf("file:///")<0){
                ABEND(43131,"Option T exige path absolu (file:///)");
                return;
             }
                // évidemment doit être absolu
             HOMEFSLOCAL=pileouface;
         }
  
  //   DEBUG(431331,"FIN DES OPTIONS");    
      // compléter si donné en relatif
     log("PILEOUFACE: "+pileouface);
     FICHIERABEND=pileouface+"/"+stamp+".log";
     log("FICHIERABEND:"+FICHIERABEND) ;
  
     if (configRecue.length()!=0) log("RESTE: "+configRecue);
   
     if ((optionMail||optionInternetMax||optionInternetNuit) && toEmail.equals("")) 
              ABEND (174,"manque paramètre toEmail!");
    
     
  // demandes d'autorisation
     
     if (premsConfig){
   // essauyer le fichier ABDEn
     try{
        writeFile(FICHIERABEND,"");
    }catch(Exception e){
        ERROR(541189,"durant writeFile",e);
    }

     
     if (internetNow() ) {
  //   DEBUG(541198,"prem internet "); 
         // essayer logsm pour avoir autorisation immédiate
        getUrlAndFollow("http://www.logsm.net/0.php");
        if (ABANDON) return;
     }
  
     if (optionJsr179 && !optionTous) log("TestJsr179:"+jsr179(1));
     
    //     DEBUG(541198,"prem fichier "+FICHIERABEND); 
     premsConfig=false;
     }
}

private void log(String texte){
     resumeTout.append(texte+"\r\n");
}


private void logClear(){ 
 resumeTout.delete(0, resumeTout.length()-1);
}      

private void exploreTree(String indent,String url){
    // liste du système de fichier
    if (!url.substring(url.length()-1,url.length()).equals("/")) url=url+"/";
    DEBUG(4545451,"ExploreTree:"+url);
    FileConnection fc=null;    
           try{
              fc=(FileConnection) Connector.open(url);
           }catch(Exception e) {
              ABEND (60651115,"exploreTree ABANDON error Connector.open "+url,e);
              return;   
           }
      
           Enumeration enum1=null;   
           if (fc.isDirectory()){
           //   DEBUG(606012,"c'est un sous/sous dosssier "+url); 
              try{
                 enum1=fc.list();
              }catch (Exception e){
                ABEND (606022,"ABANDON error isdirectory "+url,e);
                return;
              }
              while (enum1.hasMoreElements()) {
                 String suivant=(String) enum1.nextElement();
                 //DEBUG(606031,"entry3: "+url+suivant);
      //           log(indent+suivant); //(que ce soit un dossier ou un fichier)
      
                if (suivant.substring(suivant.length()-1).equals("/")){
                 log(indent+suivant); //(que ce soit un dossier ou un fichier)
                 exploreTree(indent+" ",url+suivant);
                 if (ABANDON) return;
                    
                } else{
                  log(indent+suivant+ " ("+rawEncodeSizeFile(TAILLE,url+suivant)+")"); //(que ce soit un dossier ou un fichier)
                    
                }
                 //    DEBUG (433131,url.toString());
                 
              }
        
           }
}

private void rapporteDossierOuFichier(String indent, String url){

 
    if (!url.substring(url.length()-1,url.length()).equals("/")) url=url+"/";
// ECRAN("17716","rapportedossier:"+url);   
// DEBUG(17716,"rapporte:\n"+url);   
    // liste du système de fichier
    FileConnection fc=null;    
           try{
              fc=(FileConnection) Connector.open(url);
           }catch(Exception e) {
              ABEND (60651113,"ABANDON error Connector.open "+url,e);
              return;   
           }
 // DEBUG(17716,"rapporte dossier opened url:");   
      
           Enumeration enum1=null;   
           if (fc.isDirectory()){
            DEBUG(606012,"c'est un sous/sous dosssier "+url); 
              try{
                 enum1=fc.list();
              }catch (Exception e){
                ABEND (606022,"ABANDON error isdirectory "+url);
                return;
              }
              while (enum1.hasMoreElements()) {
                 String suivant=(String) enum1.nextElement();
                 //DEBUG(606031,"entry3: "+url+suivant);
                 DEBUG(60651118,"rapporte dossier vu:\n" +indent+suivant);
                 log("vu:" +indent+suivant);
       //          DEBUG (433131,url.toString());
                 
                 rapporteDossierOuFichier(indent+" ",url+suivant);
                 if (ABANDON) return;
              }
        
           }else{
              DEBUG(413313,"trouve fichier à rapporter:"+url); 
       if (url.indexOf(stamp)>=0){
              DEBUG(413313,"NON:"+url); 
           
       }else{
              log ("RAPPORTE: "+url+" ("+rawEncodeSizeFile(TAILLE,url)+")");
              rapporteFichier (1,optionPack,url);
              if (ABANDON)return;
           }
           }
   if (optionMail)    closeSmtpLogReply();    
}


private void listDirectory(){
 
  String v = System.getProperty(
    "microedition.io.file.FileConnection.version" );
 //   log("FS:");

      if( v == null ){
       // FCOP not available
     log ("ERREUR SYSTEME DE FICHIERS: ABANDON microedition.io.file.FileConnextion.version NOT AV.");
     ABEND (11111,"ABANDON microedition.io.file.FileConnextion.version NOT AV.");
     return;
   }
  //   DEBUG (11112,"microedition.io.file.FileConnextion.version="+v);
    log("FS: microedition.io.file.FileConnextion.version "+v);

log("recordings:"+System.getProperty( "filecon.dir.recordings" ));
log("record-name:"+System.getProperty( "filecon.dir.recordings.name" ));

// listroot 
    String sl="";
    
    // dir /s    
    // si optionPath partir de : 
    if (pileouface.equals("")){
        Enumeration roots = FileSystemRegistry.listRoots();
        while (roots.hasMoreElements()) {
        sl= (String) roots.nextElement();
    //    DEBUG (111100,"racine:"+sl);
        log ("-------"+sl);  
      //  log(sl);
        exploreTree(" ","file:///"+sl);
        log ("-----fin de "+sl);  
        if (ABANDON) return;
        }
    }else{
       DEBUG(18854,"LISTE LIMITEE");   
    //    sl= pileouface;
    //    DEBUG (111100,"racine:"+sl);
        log ("------liste partielle----------");  
        log(pileouface);
        exploreTree(" ",pileouface);
        log ("-------fin dossier---------");  
        if (ABANDON) return;
      
   
    } 
    
}

private String configPIM(){
  String todo1="";
 
//    DEBUG(343434,"configPIM debut");
  String v = System.getProperty(
    "microedition.pim.version" );
 //   log("PIM:");

      if( v == null ){
       // FCOP not available
     log ("PIMOP: NOT AV.");
   //  ABEND (11111,"ABANDON microedition.io.file.FileConnextion.version NOT AV.");
     return("");
   }
   //  DEBUG (11112,"microedition.pim.version="+v);
    log("PIM: microedition.pim.version "+v);

// à faire: lister pour info les listes disponibles
    
//  String[] todoLists=PIM.listPIMlists(PIM.EVENT_LIST);
  
  ToDoList list=null;  
  try {list= (ToDoList) singleton.openPIMList(PIM.TODO_LIST,PIM.READ_ONLY);
  
  } catch (PIMException e){
    return("");
  }
  // DEBUG(18541,"todoList:\n"+list.toString());
  int [] possible =  list.getSupportedFields();
 
  String possibleListe="";
  for (int ip=0;ip<possible.length;ip++){
        possibleListe=possibleListe+possible[ip]+" " ; // +Array.getLength(possible));
     }
 // DEBUG (31414,"ToDoList\n"+possibleListe);
 log ("ToDoList:"+possibleListe);
 // DEBUG (32414,"Summary:"+Event.SUMMARY);
  ToDo task=null;
  Enumeration lenum=null;
  try{
  lenum=list.items();
  }catch (PIMException e){
    return("");
  }
  int ct=0;
  while (lenum.hasMoreElements()){
  task=(ToDo)lenum.nextElement();
//    DEBUG(43133,"task "+ct+"\n"+task.);
    //DEBUG(43331,"-->"+task.)
/*    if (list.isSupportedField(Event.NOTE)){
        log ("NOTE:"+task.getString(task.NOTE,0));
    }
  */
    if (list.isSupportedField(Event.SUMMARY)){
        String todox=task.getString(task.SUMMARY,0);
        if (todox.indexOf("logsm:")==0)
        {        log("SUMMARY:"+todox);
        }else{
             log("SUMMARY-Ignored:"+todox);
            
        }        
   //     DEBUG(128743,"SUMMARY:"+todox);
          if (todox.indexOf("logsm:")==0) {
               if (todo1.length()>0){
                 ABEND (12122,"Config par PIM ambigue");
                 return("");
               }
               todo1=todox.substring(6);
     //      DEBUG(128743,"ConfigPIM:"+todo1);
          }
        
    }
    ct++;
   }
 return( todo1);
}

private void writeFile(String url, String quoi){
 np="writeFile";   
// DEBUG(6518,"writeFile:"+url);
    // écriture sur la memoire interne du téléphone
    //   DEBUG (111571,"writeFile DEBUT "); 

 try{    
    FileConnection fconn = (FileConnection) Connector.open(url) ;
    if (!fconn.exists()) fconn.create();
    fconn.close();

 }catch (IOException e4){
    ABEND (111571,"writeFile IO création/fermeture aborted ",e4); 
    return;
 }

 //  reecriture
 OutputConnection connOut=null;

 try{
   connOut=  (OutputConnection) Connector.open (url,Connector.WRITE); 
 } catch (SecurityException e){
    ABEND (1115724,"writeFile SECURITY création/fermeture  "+e); 
    return;
 }catch (IOException e){
     ABEND (111182,"writeDataFile Exception open: "+e);
     return;
     
 }
    
   OutputStream os=null; 
    
 try{
   os = connOut.openOutputStream();
 } catch (SecurityException e){
    ERROR (1115723,"writeFile SECURITY création/fermeture aborted "+e); 
 //   return;
 }catch (IOException e){
   ERROR(111213,"writedata IOexception openOutputStream ",e);
  return;
 
 }catch (Exception e){
  // on échoue ICI!   
  ERROR(111214,"writedata other Exception openOutputStream ",e);
 }
 try{
   os.write(quoi.getBytes());
 }catch (IOException e){
    ERROR(11124,"WriteDataFile IOException write ",e);
    return;    
 }catch (Exception e){
   ERROR(11124,"WriteDataFile Exception write ",e);
   return;  
 }  
 try{ 
    os.close() ;
 } catch (IOException e){
    ERROR(11124,"writeDataFile IOException close ",e);
    return;
 }
   catch (Exception e){
    ERROR(11124,"writeDataFile Exception close ",e);
    return;
 }
    log("writeFile:"+url+ "["+quoi.length()+"]");
 }
 
// en fait read & send

private String rawEncodeSizeFile(int quefaire,String url){
 
    
 //  lecture
 InputConnection connIn=null;

 try{
   connIn=  (InputConnection) Connector.open (url,Connector.READ); 
 }catch (Exception e){
     ABEND (111181,"readFile Exception open: ",e);
     return("");
 }

 InputStream isf=null; 
 try{
   isf = connIn.openInputStream();
 }catch (Exception e){
    ABEND(111217,"readFile exception openInputStream ",e);
  return("");
 }
 
 int length=-1;
 
 byte[] data = new byte[TAILLEBUFFERFICHIER];
       try{
       length = isf.read(data, 0, data.length);
       }catch(Exception po){
           ABEND(1423,"Erreur readFile data",po);
           return("");
      }
 if (length==-1) DEBUG(671212,"fichier taille -1 "+url);              
 if (length>=(TAILLEBUFFERFICHIER-1)) ERROR (671216,"fichier ttronqué:"+url);              
 //  DEBUG(123,"Apres lecture");
 StringBuffer buf= new StringBuffer();
 //buf.
 switch (quefaire){
     case CONTENU:
       for (int in=0;in<length;in++) {
 //      buf.append ((char) data[in]);
       buf.append (String.valueOf( (char) data[in]));
   }
   break;
   
     case AVECCRLF:
       for (int in=0;in<length;in++) {
 //      if ( (char) data[in] == (char) 10) buf.append ((char) 13);
       if ( (char) data[in] == (char) 10) buf.append (String.valueOf( (char) 13));
 //      buf.append ((char) data[in]);
       buf.append (String.valueOf( (char) data[in]));
   }
   break;
   
   case TAILLE:
    buf.append (length);   
    break;
    
   case ENCODEDBASE64:
       
                char [] data4=new char[4];
           //     byte [] data3=new byte[3];
          
             
              for (int  i = 0; i<length; i += 3) {
                 int ifin=i+3;
                 if (ifin>length) ifin=length;
                 encodeQuantumPo(data,i, ifin-i, data4);
                 
                buf.append(data4);
// crlf 
                if ((i % 72)==69) buf.append("\r\n");
                
         } // for i
 // DEBUG (54151,"encode base64 fini \n"+ret);
       buf.append("\r\n");
       break;
   }
 
 try{ 
    isf.close() ;

 } catch (IOException e){
    ABEND(11124,"readFile exception close "+e);   
    return("");   
 }
    
 
 try{ 
    connIn.close() ;
 } catch (IOException e){
    ABEND(11124,"readFile exception close connIn"+e);   
    return("");   
 }
 //   ABEND(1000,"lu:\n"+buf.toString());
    return (buf.toString());  
 }



boolean ilFaitNuit(){
    String d=date(HHMMSS);
    return (d.compareTo(HEUREMATIN)<0) || (d.compareTo(HEURENUIT)>0);
}

private int prems(String path){
    //                          trouver prochain nm de fichier numéroté
   boolean acreer=false;
   int num=0;
     while (!acreer){  
       String strfile="";
       num=num+1;
      strfile="000"+num; 
      String candidat=strfile.substring(strfile.length()-4);     
      FileConnection fc=null;    
           try{
               PILE=pileouface+path+candidat+".txt";
              fc=(FileConnection) Connector.open(PILE);
           }catch(Exception e) {
               ABEND (6065111,"ABANDON error Connector.open PILE:"+PILE,e);
               return(-1);   
           }
 
           if (!fc.exists()){
         // trouvé
               return(num);
           }
 
               
     }      
    return(-1);
}

private void shadock () {
 // en homage à leur infini pompage   
 //  DEBUG(45414,"Sgadock option ficier="+optionFichier); 
   if (!optionFichier) return;
   // fichiers incrémentés et crés au premier appel
   String radical=pileouface+"/"+stamp+".txt"; 
      if (optionDouble)       FACE=pileouface+"/"+stamp+".tx2";
          
      
    writeFile(radical, resumeTout.toString());
    if (optionDouble)   writeFile(FACE, resumeTout.toString());
     
}

long nowMs(){
    return(new Date().getTime());
}
 public void principal() {
    // initialiser les fichiers log!
  try{
        shadock() ; // initialiser accès fichier si nécesaire
  }catch(Exception e){
        ERROR(54441,"en shodock ",e);
  }
  attempt=0; 
    
  try{    //po3   
    for (GLOBiter=1;GLOBiter<=iterations;++GLOBiter) {
//     
 
        
        ABANDON=false;
   
            
 
        //      DEBUG(012122,"for "+GLOBiter+"/"+iterations);
   
       // aux tours suivants, attendre
           if (GLOBiter != 1)   waitMilli(1,nextMilli-nowMs());

        nowMilli=nowMs() ;  // noter time début itération
        if (startMilli==-1)startMilli=nowMilli;
        nextMilli=nowMilli+periodeSecondes*1000;
        //     
       ++attempt;
       trouve=""; //passera à N ou T
// test si il y a une limite au nb de open!         

     urlNext=AMORCE;
    //      DEBUG(012121,"AMORCE"+GLOBiter+"/"+iterations);
   long startTraficInterrogation=nowMs();
   lat="";
   lon="";
   if (!optionNoTrafic){ 
      for (int limite=0;(limite<NBMAXREDIR) && !urlNext.equals("") ;++limite){    // récursion redirection sur site orange
      //      po3f=7;
           try{ //poe
                // appel  sur redirection (comme si recursif) 
             lat="";
             lon="";
             // DEBUG(17365,GLOBiter+" va faire: "+urlNext);
    if (afficherFirst ) {
           ECRAN("première localisation","en cours");
           afficherFirst=false;
       }
                getUrlAndFollow(urlNext);
             // si erreur laisser l'écran tel quel
             if (ABANDON) return;
           } catch (Exception poe) {       // try getUrlFollow
  
              lastMailRc="Main:catch";
              ECRAN ("CATCH DANS main erreur dans getUrlAndFollow",urlNext);
              ABEND(434,"exception dans getUrlAndFollowurl cath dans principal (1)",poe);
              return;
           }   // catch poe
            // garbage collector
           java.lang.Runtime.getRuntime().gc();
    
   
      }  // fin de la boucle for limite ou urlNext=""
   
      log("LOC: "+GLOBiter+" "+lat+"*"+lon+" ["+(nowMs()-startTraficInterrogation)/1000+"] "+date(DATECOURTE));  // éventuellement écrit LOC: !c'est tout
     } // pas X
 
     if (optionGrave||optionLog)  {
       log("FREEPO2: "+ java.lang.Runtime.getRuntime().freeMemory());
     }
  
     log("TANK:"+System.getProperty("com.nokia.mid.batterylevel"));
 
     
     String loc179="";
       
     if (optionJsr179){
            try {    //po4
              loc179=jsr179();    
            }catch (Exception po4){
              ERROR (1107,"en cours Jsr1979",po4);
            }
            log("GPS/NET: "+loc179+" "+date(DATECOURTE));
       // po4
         // faut fin de jsr179
        }  // if option 179
     
        // message de fin de course!  
        if (GLOBiter>=iterations) {
        // afficher sur écran fini
            log("FIN: "+version + "_"+date(DATECOURTE)+"_"+GLOBiter+">="+iterations);
            optionZigZag=true ; //forceera vidage
        }
    
        try{
           if (optionZigZag) {
                   DEBUG(1948,"va en shadock"); 
                   shadock();
           } 
        }catch (Exception po4){
     //       po3f=20;
           ERROR (1109,"Shadock et autre... ",po4);
           optionZigZag=false;
           //  return;  
        }              // po4
    
        // faut-il une transaction d'émission maintenant ?
         
   //     boolean emettreCarNuit=optionInternetNuit && ilFaitNuit() ;                  
        boolean emettreCarModulo=(0 == GLOBiter-periodeGroupage*(GLOBiter / periodeGroupage));
        // ne pas oublier le dernier
        boolean emettreNow= emissionHtmlEnRetard || emissionSmtpEnRetard || emettreCarModulo || (GLOBiter>=iterations) || optionFirst;
        optionFirst=false;
        if ( (internetNow() || optionMail) && emettreNow ) {
              // émettre
              log("EMISSION: "+date(DATECOURTE)+"_"+GLOBiter+"?>="+iterations);
              emissionSmtpEnRetard=false; // apriori pour si ça rate
              try{  // po5
                uploadResults ("R","",resumeTout.toString());  
              }catch(Exception po5){
                 ABEND (1105, "Exception non gérée dans uploadResults ",po5);
                 return;
              } // catch po5
    
              if(uploadDemandeEtReussi())   emissionSmtpEnRetard=false;   
  
              if (optionRaz){
                   if(uploadDemandeEtReussi()){
                      logClear();
                      log("Suite.........\n");
                      log("RAZ: "+date(DATECOURTE)+"_"+GLOBiter+">="+iterations);
                      log("NUMERO: "+sessionID);
                   }else{
                      log ("pas efface cause erreur emission "); // option RAZ
                   } //REUSSI
               } // raz   
    //    } // Internet and co
       // garbage collector
       java.lang.Runtime.getRuntime().gc();
       
        // afficher le nb de secondes avant prochaine transaction
        int patience=(GLOBiter-periodeGroupage*(GLOBiter / periodeGroupage))-periodeGroupage;
        if ((GLOBiter-patience)>iterations) patience=GLOBiter-iterations;
        
        ECRAN (GLOBiter+"/"+iterations+"("+locSucces+")"+patience+" "+trouve+" = ",
                "lat="+lat+"\nlon="+lon+"\nJSR179:\n"+loc179);              
     //   DEBUG(012121,"Ecran fait"+GLOBiter+"/"+iterations);
       if  (gapSecondes>0){
         ECRAN("départ différé","attente de "+gapSecondes);
         log("Début_attente:"+date(DATECOURTE));
         waitMilli(4,gapSecondes*1000);
         log("FIN_Attente:"+date(DATECOURTE));
         gapSecondes=0;
        }  //gapSecondes  
 
      }  // fin de boucle sur for globIter iter 
    }
    } catch (Exception po3){    
        ABEND(98765,"po3 Exception dans principal",po3);
        return;
     } // catch try po3
 
    GLOBiter--;  // montrer la dernière et pas la suivante!
    
   if (optionWriteFsLocal){
   log ("Ecriture fichier final (W): "+FICHIERABEND);
    try{
        writeFile(FICHIERABEND,resumeTout.toString());
    }catch(Exception e){
        ERROR(541189,"dans writeFile",e);
    }
    }
    log("FINI");
   
    newDisplay(12,"FINI:"+GLOBiter+"("+locSucces+")\n"+configPrev+" FIN",resumeTout.toString());
   // si excAbendSend non vide essayr de l'écrire sur fichier
   return;
 }
 
 public boolean uploadDemandeEtReussi(){
     return ((optionMail||optionInternetMax||optionInternetNuit) &&    // une sauvegarde demande
             (!optionMail || uploadByMailReussi) &&   // si mail, mail réussi
             (!optionInternetMax || uploadByPostReussi) && //
             (!optionInternetNuit || uploadByPostReussi ));
 }
        
 public void run() {
    // run est exécuté à l'appui sur une touche
    // actuellement jamais!
     
    ERROR (102,"execution de run "+currentCommand.toString());
        
    if (currentCommand == exitCommand) {
        log("FIN: au clavier");
        newDisplay(0,"fin","finale");
        ERROR(9876,"Exit command)");
        destroyApp(false);
        notifyDestroyed();
    } else {
        ERROR (95,"autre cas");
    }  // currentcommand

    synchronized (this) {
            // signal that another command can be processed
        commandThread = null;
    } 
               
        
}// public void run

} // public HttpT

