/* display - various display functions
 */

#include "pico.h"
#include <string.h>

void pico_banner(Picovars *vars) {
 static int a,b;
 b=standout(vars->screendata,1);
 a=strlen(vars->filename);
 if (a>=(vars->screendata->width)) a=(vars->screendata->width)-1;
 strcpy(vars->temp,(vars->filename)+strlen(vars->filename)-a);
 move(vars->screendata,0,0); addstr(vars->screendata,vars->temp);
 while (a<(vars->screendata->width)) {addch(vars->screendata,' '); a++;}
 move(vars->screendata,0,(vars->screendata->height)-1);
 for(a=0; a<vars->screendata->width; a++) {addch(vars->screendata,' ');}
 standout(vars->screendata,b);
}

void pico_status(Picovars *vars,char *status) {
 static int a,b,x,y;
 b=standout(vars->screendata,1);
 x=vars->screendata->x; y=vars->screendata->y;
 move(vars->screendata,0,(vars->screendata->height)-1);
 for(a=0; a<((vars->screendata->width-strlen(status))/2); a++) {
  addch(vars->screendata,' ');}
 addstr(vars->screendata,status);
 for(a=0; a<=((vars->screendata->width-strlen(status))/2); a++) {
  addch(vars->screendata,' ');}
 standout(vars->screendata,b); move(vars->screendata,x,y);
 refresh(vars->screendata);
}

void pico_screen(Picovars *vars) {
 static int y;
 for(y=1; y<(vars->screendata->height-1); y++) {
  pico_displayline(vars,vars->toprow+y-1);}
}

void pico_displayline(Picovars *vars,short row) {
 static long position,mposmin,mposmax;
 static short x,c,v,w;
 static char a,e;
 if (row<vars->toprow) return;
 if (row>(vars->toprow+vars->screendata->height-3)) return;
 v=vars->screendata->x; w=vars->screendata->y;
 move(vars->screendata,0,(row-vars->toprow)+1);
 a=standout(vars->screendata,0);
 if (vars->mark!=-1) {
  mposmin=vars->mark+vars->markcol; mposmax=vars->position+vars->column;
  if (mposmin>mposmax) {mposmin=mposmax; mposmax=vars->mark+vars->markcol;}
 }
 if (row==vars->row) {
  position=vars->leftcol;
  e=0; for(x=0; x<vars->screendata->width; x++) {
   if (e) {c=32;} else {c=vars->linebuf[position]; position++;}
   if ((c==10) || (c==0)) {e=1; c=32;}
   if (vars->mark!=-1) {
    if (((vars->position+position-1)>=mposmin) &&
        ((vars->position+position-1)<mposmax) && (!e)) {
     standout(vars->screendata,1);
    } else {
     standout(vars->screendata,0);
    }
   }
   if ((x==(vars->screendata->width-1)) && (e==0)) c='$';
   addch(vars->screendata,c);
  }
 } else {
  position=pico_findline(vars,row);
  e=0; for(x=0; x<vars->screendata->width; x++) {
   if (e) {c=32;} else {c=pico_readchar(vars,position); position++;}
   if ((c==10) || (c==0)) {e=1; c=32;}
   if (vars->mark!=-1) {
    if (((position-1)>=mposmin) && ((position-1)<mposmax) && (!e)) {
     standout(vars->screendata,1);
    } else {
     standout(vars->screendata,0);
    }
   }
   if ((x==(vars->screendata->width-1)) && (e==0)) c='$';
   addch(vars->screendata,c);
  }
 }
 standout(vars->screendata,a); move(vars->screendata,v,w);
}

void pico_position(Picovars *vars) {
 refresh(vars->screendata);
 sprintf(vars->temp,"Row %d, Column %d",vars->row+1,vars->column+1);
 pico_status(vars,vars->temp);
}

void pico_endline(Picovars *vars) {
 vars->column=strlen(vars->linebuf);
 vars->leftcol=0;
 if (vars->column>=vars->screendata->width)
  vars->leftcol=5+vars->column-(vars->screendata->width);
 move(vars->screendata,vars->column-vars->leftcol,vars->screendata->y);
 pico_displayline(vars,vars->row);
 pico_position(vars);
}

void pico_pageup(Picovars *vars) {
 static short row;
 pico_storeline(vars);
 row=vars->row-(vars->screendata->height-4);
 if (row<0) row=0;
 vars->position=pico_findline(vars,row);
 vars->row=row;
 row-=2; if (row<0) row=0;
 vars->toppos=pico_findline(vars,row);
 vars->toprow=row;
 pico_readline(vars);
 if (vars->column>strlen(vars->linebuf)) pico_endline(vars);
 move(vars->screendata,vars->screendata->x,1+vars->row-vars->toprow);
 pico_screen(vars);
 pico_position(vars);
 vars->moved=1;
}

void pico_pagedown(Picovars *vars) {
 static short row;
 pico_storeline(vars);
 row=vars->row+(vars->screendata->height-4);
 if (row>=(vars->numrows)) row=vars->numrows-1;
 if (row<0) row=0;
 vars->position=pico_findline(vars,row);
 vars->row=row;
 row-=(vars->screendata->height-4); if (row<0) row=0;
 vars->toppos=pico_findline(vars,row);
 vars->toprow=row;
 pico_readline(vars);
 if (vars->column>strlen(vars->linebuf)) pico_endline(vars);
 move(vars->screendata,vars->screendata->x,1+vars->row-vars->toprow);
 pico_screen(vars);
 pico_position(vars);
 vars->moved=1;
}

void pico_left(Picovars *vars) {
 if (vars->column==0) {
  if (vars->row==0) return;
  pico_up(vars); pico_endline(vars);
  return;
 }
 (vars->column)--;
 if (vars->column<=vars->leftcol)
  vars->leftcol-=(vars->screendata->width/2);
 if (vars->leftcol<0) vars->leftcol=0;
 move(vars->screendata,vars->column-vars->leftcol,vars->screendata->y);
 pico_displayline(vars,vars->row);
 pico_position(vars);
}

void pico_right(Picovars *vars) {
 if (vars->column>=strlen(vars->linebuf)) {
  move(vars->screendata,0,vars->screendata->y);
  vars->column=0; vars->leftcol=0; pico_down(vars);
  return;
 }
 (vars->column)++;
 if ((vars->column-vars->leftcol)>=(vars->screendata->width-1))
  vars->leftcol+=(vars->screendata->width/2);
 move(vars->screendata,vars->column-vars->leftcol,vars->screendata->y);
 pico_displayline(vars,vars->row);
 pico_position(vars);
}

void pico_up(Picovars *vars) {
 static short row,oldrow,oldtoprow;
 if (vars->row<=0) return;
 oldtoprow=vars->toprow; oldrow=vars->row;
 if ((vars->linebuf[0]>0) || (vars->linelength>0)) pico_storeline(vars);
 vars->position=pico_findline(vars,vars->row-1);
 (vars->row)--;
 if (vars->row<=vars->toprow) {
  row=vars->toprow-(vars->screendata->height-5);
  if (row<0) row=0;
  vars->toppos=pico_findline(vars,row);
  vars->toprow=row;
 }
 pico_readline(vars);
 if (vars->column>strlen(vars->linebuf)) pico_endline(vars);
 move(vars->screendata,vars->screendata->x,1+vars->row-vars->toprow);
 if (oldtoprow!=vars->toprow) {
  pico_screen(vars);
 } else {
  if (vars->row!=oldrow) pico_displayline(vars,oldrow);
  pico_displayline(vars,vars->row);
 }
 pico_position(vars);
 vars->moved=1;
}

void pico_down(Picovars *vars) {
 static short oldrow,oldtoprow;
 if (vars->row>=vars->numrows) return;
 oldtoprow=vars->toprow; oldrow=vars->row;
 pico_storeline(vars);
 vars->position=pico_findline(vars,vars->row+1);
 (vars->row)++;
 if ((vars->row-vars->toprow)>(vars->screendata->height-4)) {
  vars->toppos=vars->position;
  vars->toprow=vars->row;
 }
 pico_readline(vars);
 if (vars->column>strlen(vars->linebuf)) pico_endline(vars);
 move(vars->screendata,vars->screendata->x,1+vars->row-vars->toprow);
 if (oldtoprow!=vars->toprow) {
  pico_screen(vars);
 } else {
  if (vars->row!=oldrow) pico_displayline(vars,oldrow);
  pico_displayline(vars,vars->row);
 }
 pico_position(vars);
 vars->moved=1;
}

void pico_fullpos(Picovars *vars) {
 refresh(vars->screendata);
 if (vars->filesize>0) {
  sprintf(vars->temp,"Row %d/%d, Column %d - byte %ld/%ld (%d%%)",
          vars->row+1,vars->numrows+1,vars->column+1,
          vars->position+vars->column+1,vars->filesize+1,
          100*(vars->position+vars->column)/vars->filesize);
  pico_status(vars,vars->temp);
 } else {pico_status(vars,"New Buffer");}
}

int pico_input(Picovars *vars,char *string) {
 static int i,c,x;
 i=strlen(string); x=vars->screendata->x;
 addstr(vars->screendata,string); refresh(vars->screendata);
 do {
  c=readchar();
  if (c==8) c=127;
  if ((c>31) && (c<127)) {
   string[i]=c; i++; string[i]=0;
   addch(vars->screendata,c);
  }
  if ((c==127) && (i>0)) {
   i--; string[i]=0;
   move(vars->screendata,vars->screendata->x-1,vars->screendata->y);
   addch(vars->screendata,' ');
   move(vars->screendata,vars->screendata->x-1,vars->screendata->y);
  }
  refresh(vars->screendata);
 } while (c>31);
 return(c);
}
