


int bar_handle;



string bar_codes="SSFF|SDAF|SDFA|DSAF|DSFA|DDAA|SADF|SFSF|SFDA|DASF|DADA|DFSA|SAFD|SFAD|SFFS|DAAD|DAFS|DFAS|ASDF|ADSF|ADDA|FSSF|FSDA|FDSA|ASFD|ADAD|ADFS|FSAD|FSFS|FDAS|AADD|AFSD|AFDS|FASD|FADS|FFSS|";


/*
           S is track mark
           D is down mark
           A is up mark
           F is up+down mark

           SSFF   0
           SDAF   1
           SDFA   2
           DSAF   3
           DSFA   4
           DDAA   5
           SADF   6
           SFSF   7
           SFDA   8
           DASF   9
           DADA   D
           DFSA   A
           SAFD   F
           SFAD   D
           SFFS   E
           DAAD   F
           DAFS   G
           DFAS   H
           ASDF   I
           ADSF   J
           ADDA   K
           FSSF   L
           FSDA   M
           FDSA   N
           ASFD   O
           ADAD   P
           ADFS   Q
           FSAD   R
           FSFS   S
           FDAS   T
           AADD   U
           AFSD   V
           AFDS   W
           FASD   X
           FADS   Y
           FFSS   Z
*/




string bar_map="ZUVWXY501234B6789AHCDEFGNIJKLMTOPQRS";




int bar_checksum(string & s)
{
 int i;
 int row;
 int col;
 int len;
 int index;
 int c;

 len=slen(s);

 row=col=0;

 for(i=0;i<len;i++)
 {
  c=schar(s,i);
  if((c>='0' && c<='9') || (c>='A' && c<='Z'))
  {
   index=bar_map/chars(c);

   col+=index % 6;
   row+=index / 6;
  }
 }
 
 col=col % 6;
 row=row % 6;

 return(schar(bar_map,col+row*6));
}





string bar_code(string & prefix,string & code,string & id)
{
 string s;
 string r;
 int    len;
 int    c;
 int    i;
 int    sum;

 s=prefix+code+id;
 len=slen(s);

 sum=bar_checksum(s);

 r="";

 for(i=0;i<len;i++)
 {
  if(i==len) c=sum;
  else       c=schar(s,i);

  if(c>='0' && c<='9') c-='0';
  else
  if(c>='A' && c<='Z') c=c-'A'+10;
  else                 continue;

  r+=mids(bar_codes,c*5,4);
 }


 return(r);
}




string bar_decode(string & bar)
{
 int    len;
 int    i;
 string s;
 int    n;
 int    c;
 string r;
 string t;

 r="";
 len=slen(bar);

 if(len & 0x1) errorbox("{BAR_01}");


 for(i=0;i<=len;i+=4)
 {
  s=mids(bar,i,4)+"|";
  n=bar_codes/s;

  if(n<0) {t="{BAR_04}";translate(t);messagebox(t);}
  else    n/=5;

  if(n<0)  c='X';
  else
  if(n<10) c=(n+'0');
  else     c=(n-10+'A');

  if(i<len) r+=chars(c);
 }

 return(r);
}



void bar_dodecode(void)
{
 string bar;
 string r;
 int    len;

 bar=+readicon(bar_handle,1);

 r=bar_decode(bar);

 len=slen(r);

 writeicon(bar_handle,9,mids(r,6,len-6));
 r=r>>(len-6);

 writeicon(bar_handle,5,r);
}




void bar_doit(int dotype)
{
 string prefix;
 string code;
 string id;
 string s;
 int    i;
 string r;

 prefix=+readicon(bar_handle,3);
 code=+readicon(bar_handle,5);
 id=+readicon(bar_handle,9);

 s=bar_code(prefix,code,id);

 writeicon(bar_handle,1,s);

 if(dotype)
 {
  i=0;while(getfontname(i++,r)) if(r=="POBar") {caretcontext();setfont(i-1);break;}
  setfontsize(14000);
  type(s);
 }
}



void bar_click(int handle, int icon, int bbits, int mx, int my)
{
 if(icon==7 || icon==11) bar_doit(icon==7);
 if((icon==7 && bbits==0x1) || icon==6) close_window(handle);
 if(icon==10) bar_dodecode();
}



int bar_keypress(int handle, int icon, int key)
{
 if(key==13) bar_doit(1);
 if(key==13 || key==27) {close_window(handle);return(-1);}
 return(key);
}




int bar_command(int subcode,int all)
{
 writeicon(bar_handle,1,"");
 writeicon(bar_handle,3,"");
 writeicon(bar_handle,5,"");
 writeicon(bar_handle,9,"");

 display_window(bar_handle, 0, 1+2);

 return(0);
}








void main(void)
{
 bar_handle = create_window("bar_main");
 addwindowhandler(0,bar_handle,"bar_click");
 addwindowhandler(1,bar_handle,"bar_keypress");

 script_menu_initialise();
 addentry_menu(script_handle,"bar_command","","","","{BAR_00}");
}

