﻿//KyblPrectiZpravy (KyblCteckaZprav) v1.2
//http://www.kyblsoft.cz/mobil/

use contacts,graph,io,msg,proc,sms,system,time,ui

grafickyrezim=true;
fullscreen=false;
slozkazprav=msg.inbox;
uvolnitpametza=30;

function VratZpravu(id)
  str=msg.open(id);
  try
    text=io.read(str,io.avail(str));
  catch e by
    text='Zvláštní SMS';
  end;
  if len(text)>0 and code(substr(text,len(text)-1),0)=8233 then  //na konci je nejaky divny znak
    text=substr(text,0,len(text)-1);
  end;
  return text;
end;

function VyndejOdesilatele(text)
  if substr(text,0,3)='Od ' then
    t=substr(text,3);
    pozmezery=index(t,' ');
    if pozmezery=-1 then
      return null;
    end;
    odesilatel=substr(t,0,pozmezery);
    t=substr(t,pozmezery+1);
    if substr(t,0,1)=' ' then
      t=substr(t,1);
    end;
    return ['text': t,'odesilatel': odesilatel];
  else
    return null;
  end;
end;

function ProjdeFiltrem(text,odesilatel,filtr)
  case filtr
    in 'vse': return true;
    in 'ucet': return (odesilatel = '39901')
    in 'jine': return not ProjdeFiltrem(text,odesilatel,'ucet');
  end;
end;

function OznacPrectenou(id)
  sms.set(id,['unread': false]);
end;

function JeTelefonniCislo(cislo)
  c=cislo;
  if substr(c,0,1) = '+' then
    c=substr(c,1);
  end;

  while len(c) > 0 do
    znak=code(c,0);
    if znak < code('0',0) or znak > code('9',0) then
      return false;
    end;
    c=substr(c,1);
  end;
  return true;
end;

function DosadOdesilatele(odes)
  if not JeTelefonniCislo(odes) then
    return odes;
  end;

  kontakty=contacts.findnr(odes,13);
  if len(kontakty) = 0 then
    return odes;
  end;

  kontakt=contacts.get(kontakty[0]);
  if kontakt['fname'] # null then
    jmeno=kontakt['fname'];
    if kontakt['name'] # null then
      jmeno=jmeno+' '+kontakt['name'];
    end;
  elsif kontakt['name'] # null then
    jmeno=kontakt['name'];
  else
    jmeno='';
  end;
  
  return jmeno;
end;

function JeZBrany(text)
  try
    if num(substr(text,0,1)) = 0 or substr(text,1,1) # '/' or num(substr(text,2,1)) = 0 or substr(text,3,5) # ' www:' then
      return false;
    end;
  catch ExcInvalidNumber by
    return false;
  end;
  return true;
end;

function SpojZpravyZBrany(text,odeszpravy)
  if not JeZBrany(text) then
    return null;
  end;
  texty=[];
  pocet=num(substr(text,2,1));
  poz=len(odeszpravy)-1;
  if pocet>(poz+1) then
    return null;  //zbyva malo zprav
  end;

  for i=1 to pocet do
    append(texty,null);
  end;

  for i=1 to pocet do
    novytext=VratZpravu(odeszpravy[poz]);
    if not JeZBrany(novytext) or num(substr(novytext,2,1)) # pocet or texty[num(substr(novytext,0,1))-1] # null then
      return null;   //je jina zprava
    end;
    texty[num(substr(novytext,0,1))-1]=novytext;

    poz--;
  end;

  vysledek=[];
  vysledek['text']='';
  for txt in texty do
    vysledek['text'] = vysledek['text']+substr(txt,8);
  end;

  poz=len(odeszpravy);
  vysledek['zobrazenaid']=[];
  vysledek['zobrazenepozice']=[];
  for i=1 to pocet do
    append(vysledek['zobrazenaid'],odeszpravy[poz-i]);
    append(vysledek['zobrazenepozice'],poz-i);
  end;

  return vysledek;
end;

function VratDenVTydnu(cas)
  case time.dayofweek(cas)
    in 0: return 'pondělí';
    in 1: return 'úterý';
    in 2: return 'středa';
    in 3: return 'čtvrtek';
    in 4: return 'pátek';
    in 5: return 'sobota';
    in 6: return 'neděle';
  end;
end;

function VratNoveZpravy(slozkazprav)
  ui.busy('Načítám zprávy...');
  zpravy=null;
  system.gc(); //je jich hodne

  return msg.scan(slozkazprav);
  //return sms.inbox();
end;

function VratPosledniZpravu(minpozice,zpravy,poslid)
  zprava=null;
  predodesilatel=null;

  for i=minpozice to len(zpravy)-1 do
    if zpravy[i]['id']=poslid then
      break;
    end;
    if zpravy[i]['descr2']#predodesilatel then
      odeszpravy=[];
      predodesilatel=zpravy[i]['descr2'];
    end;
    append(odeszpravy,zpravy[i]['id']);
    zprava=zpravy[i];
  end;
  pozice=i;

  if zprava=null then  //konec
    return null;
  end;

  text=VratZpravu(zprava['id']);
  odesilatel=DosadOdesilatele(zprava['descr2']);

  zobrazenaid=[zprava['id']];

  if zprava['descr2']='e-mail' then
    vysledek=VyndejOdesilatele(text);
    if vysledek # null then
      text=vysledek['text'];
      odesilatel=vysledek['odesilatel'];

    elsif substr(text,len(text)-4)=' 2/2' and len(odeszpravy)>1 then
      text2=VratZpravu(odeszpravy[len(odeszpravy)-2]);

      if substr(text2,len(text2)-4)=' 1/2' then
        vysledek=VyndejOdesilatele(text2);
        if vysledek # null then
          text2=vysledek['text'];
          odesilatel=vysledek['odesilatel'];
        end;
      
        text=substr(text2,0,len(text2)-4)+substr(text,0,len(text)-4);
        append(zobrazenaid,odeszpravy[len(odeszpravy)-2]);
      end;
    end;
  else
    vysledek=SpojZpravyZBrany(text,odeszpravy);
    if vysledek # null then
      text=vysledek['text'];
      zobrazenaid=vysledek['zobrazenaid'];
    end;
  end;

  pozice-=len(zobrazenaid)-1;

  return ['cas': zprava['time'], 'odesilatel': odesilatel, 'smsodesilatel': zprava['descr2'], 'text': text, 'zobrazenaid': zobrazenaid, 'pozice': pozice, 'neprectena': zprava['unread']]; 
end;

function VratPozRozkouskTextPoInterpunkci(radek,maxsirka,odpozice)
  poslpripustny=null;

  for i=odpozice+1 to len(radek)-1 do
    case substr(radek,i,1)
      in '+','-','*','#','/','\\','\'','"','&','#','@','=':
                            //pred i za
        if graph.size(substr(radek,0,i+1))[0] > maxsirka then
          if graph.size(substr(radek,0,i))[0] > maxsirka then
            break;
          else
            poslpripustny=i;
            dalsipoz=i;
          end;
        else
          poslpripustny=i+1;
          dalsipoz=i+1;
        end;

      in '(':
                            //pred
        if graph.size(substr(radek,0,i))[0] > maxsirka then
          break;
        else
          poslpripustny=i;
          dalsipoz=i;
        end;

      in '.',',','!','?',':',';',')','%':
                            //za
        if graph.size(substr(radek,0,i+1))[0] > maxsirka then
          break;
        else
          poslpripustny=i+1;
          dalsipoz=i+1;
        end;
    end;
  end;

  if poslpripustny = null then
    return null;  //nelze rozkousk.
  else
    return [poslpripustny,dalsipoz];
  end;
end;

function RozkouskujText(text,maxsirka)
  navrat=[];

  while text # '' do
                //rozdeleni po \n
    poz1=index(text,'\n');
    poz2=index(text,char(8233));
             //? enter v odeslanych
    if poz1 = -1 then
      poz=poz2;
    elsif poz2 = -1 then
      poz=poz1;
    elsif poz1 < poz2 then
      poz=poz1;
    else
      poz=poz2;
    end;

    if poz = -1 then
      radek=text;
      text='';
    else
      radek=substr(text,0,poz);
      text=substr(text,poz+1);
    end;

    if radek = '' then
      append(navrat,radek);
    end;

    while radek # '' do
            //rozdeleni po mezerach
      poslpripustny=-1;
      for i=1 to len(radek)-1 do
        case substr(radek,i,1)
          in ' ':
            delka=graph.size(substr(radek,0,i))[0];
            if delka > maxsirka then
              break;
            else
              poslpripustny=i;
              dalsipoz=i+1;
            end;
        end;
      end;

      if i = len(radek) and graph.size(radek)[0] <= maxsirka then
                          //cely radek
        append(navrat,radek);
        radek='';
      elsif poslpripustny > -1 then

        if graph.size(substr(radek,0,poslpripustny))[0] < maxsirka*0.7 then
          tmpnavrat=VratPozRozkouskTextPoInterpunkci(radek,maxsirka,poslpripustny);
          if tmpnavrat # null then
            poslpripustny=tmpnavrat[0];
            dalsipoz=tmpnavrat[1];
          end;
        end;

        append(navrat,substr(radek,0,poslpripustny));
        radek=substr(radek,dalsipoz);

      else
     //dlouhe slovo, zkusim rozdelit
        tmpnavrat=VratPozRozkouskTextPoInterpunkci(radek,maxsirka,0);
        if tmpnavrat # null then
          poslpripustny=tmpnavrat[0];
          dalsipoz=tmpnavrat[1];
        else

            //rozdeleni po znacich
          poslpripustny=1;
          for i=2 to len(radek)-1 do  
            delka=graph.size(substr(radek,0,i))[0];
            if delka > maxsirka then
              break;
            else
              poslpripustny=i;
              dalsipoz=i;
            end;
          end;
        end;
        append(navrat,substr(radek,0,poslpripustny));
        radek=substr(radek,dalsipoz);
      end;
    end;
  end;
  return navrat;
end;

function NapisText(pozx,pozy,text,maxsirka,maxvyska,okrajx,okrajy,pozadi=false)
  radky=RozkouskujText(text,maxsirka-2*okrajx);
  vyska=graph.size(' ')[1];
  if pozy+okrajy+len(radky)*vyska > maxvyska then
    return false;  //nevejde se
  end;
  vyskacelkem=len(radky)*vyska+2*okrajy+vyska/3;
  if pozadi # null then
    graph.brush(pozadi);
    graph.pen(pozadi);
    graph.rect(pozx,pozy,maxsirka,vyskacelkem);
    graph.pen(graph.black);
  end;
  for i=0 to len(radky)-1 do
    y=pozy+okrajy+(i+1)*vyska;
    graph.text(pozx+okrajx,y,radky[i]);
  end;

  graph.show();
  return pozy+vyskacelkem;
end;

function NapisZpravu(zprava,grafickyrezim,fullscreen)

  for id in zprava['zobrazenaid'] do
    OznacPrectenou(id);
  end;

  cas=zprava['cas']+2*3600;
  datumtext=time.str(cas,'DD.MM.YYYY');
  if time.str(time.get(),'DD.MM.YYYY') = datumtext then
    datumtext='dnes';
  else
    datumtext=VratDenVTydnu(cas)+' '+datumtext;
  end;
  if len(zprava['zobrazenaid']) = 1 then
    pocetsmstext='';
  else
    pocetsmstext=' ('+str(len(zprava['zobrazenaid']))+' sms)';
  end;

  hlavicka=datumtext+' '+time.str(cas,'hh:mm:ss')+pocetsmstext+'\n'+zprava['odesilatel'];

  if grafickyrezim then
    okrajex=5;
    okrajey=0;
    rozmery=graph.full(fullscreen);
    graph.size(rozmery[0],rozmery[1]);
    graph.brush(graph.white);
    graph.rect(0,0,rozmery[0],rozmery[1]);
    if zprava['neprectena'] then
      pozadi=0xFFFF70;
    else
      pozadi=0xC0E0FF;
    end;
    vyskahlavicky=NapisText(1,1,hlavicka,rozmery[0]-2,rozmery[1]-2,okrajex,okrajey,pozadi);
    if vyskahlavicky = false then
      grafickyrezim=false;
    else
      graph.pen(0x000000);
      if NapisText(1,vyskahlavicky+9,zprava['text'],rozmery[0],rozmery[1],okrajex,okrajey) = false then
        grafickyrezim=false;
      end;
    end;
  end;
  if not grafickyrezim then
    cls();
    graph.hide();
    print hlavicka+'\n\n'+zprava['text'];
  end;
end;

poslid=null;
minpozice=0;
skoncit=false;
filtr='vse';
zpravy=null;

while not skoncit do
  if zpravy = null then
    zpravy=VratNoveZpravy(slozkazprav);
  end;

  if poslid = null then
    minpozice=len(zpravy)-10;
    if minpozice < 0 then
      minpozice=0;
    end;
  end;

  ui.busy('Hledám...');
  poslidted=poslid;

  do
    zpravated=VratPosledniZpravu(minpozice,zpravy,poslidted);
    if zpravated = null then
      ui.busy();
      ui.msg('Žádná (další) zpráva');
      poslidted=poslid;
      break;
    else zprava=zpravated;
    end;

    minpozice=zprava['pozice']-10;
    if minpozice < 0 then
      minpozice=0;
    end;

    poslidted=zprava['zobrazenaid'][len(zprava['zobrazenaid'])-1];  //posun na dalsi
  until ProjdeFiltrem(zprava['text'],zprava['odesilatel'],filtr);

  if skoncit then
    break;
  end;

  ui.busy();

  if zprava # null then
    NapisZpravu(zprava,grafickyrezim,fullscreen);
  end;

  while true do
    ui.keys(false);
    if zpravy = null then
      zn=ui.cmd();
    else //pak uvolneni pameti
      zn=ui.cmd(uvolnitpametza*1000);
    end;

    case zn
      in 32,63562:
        poslid=poslidted;
        break;
      in 8:
        if zprava['smsodesilatel'] = 'e-mail' or ui.confirm('Smazat zprávu od: '+zprava['odesilatel']+'?','Potvrzení smazání') then
          for id in zprava['zobrazenaid'] do
            msg.delete(id);
          end;
          zpravy=null;
          break;
        end;
      in 102:    //f
        fullscreen=not fullscreen;
        break;
      in 103:    //g
        grafickyrezim=not grafickyrezim;
        break;
      in 106:    //j
        filtr='jine';
      in 113,33,81:   //q
        if grafickyrezim then
          cls();
          graph.hide();
        else
          print '\nProgram ukončen.';
        end;
        skoncit=true;
        break;
      in 114,49,82:   //r
        zpravy=null;
        poslid=null;
        break;
      in 115:   //s
     //   novaslozka=ui.list(['msg.attmt,msg.draft,msg.inbox,,multiple=false,init=[],title="mShell")
        case slozkazprav
          in msg.inbox: 
            slozkazprav=msg.sent;
          in msg.sent: 
            slozkazprav=msg.inbox;
        end;
        zpravy=null;
        poslid=null;
        break;
      in 117:    //u
        filtr='ucet';
      in 118:    //v
        filtr='vse';
      in null:   //nic
        zpravy=null;  //uvol. pameti
    end;
  end;
  
end;

proc.close();
