(********************************************
  Version: 7.0
  Date: 2003/11/25
  This is shareware.
  Copyright (C) Michal Pohanka
  All rights reserved.

  Internet: http://www.volny.cz/profipohanka
 ********************************************)

unit UPohStrConv;

interface

uses
  UPohTypes;

const
  PohDecimalSeparators = ['.',','];

  function GetDecPlacesFromStr(s: string): integer;

  function IntToStr(Value: double): string; overload;
  function HexToInt(s: string): integer; // FFFFFFFF=-1
  function PohFloatToStr(d: extended): string; overload;
  function PohFloatToStr(d: extended; decPlaces: integer): string; overload;
  function PohFloatToStr(d: extended; decPlaces, decPlacesMax: integer): string; overload;
  function PohFloatToStrEx(d: extended; decSep: char; decPlaces, decPlacesMax: integer; maxLength: integer=0): string;
  function PohStrToFloat(s: string): extended;
  function PohStrToFloatDef(s: string; default: extended): extended;

  function PohDateToString(dt: TDateTime; sepChar: string): string;

  procedure SeparateStringByTabs(var dst: TStringArray; src: string);

  procedure DecSepTo(var s: string; ch: char);
  function GetDecSepTo(s: string; ch: char): string;
  procedure DecSepToWinSep(var s: string);

implementation

uses
  SysUtils, Math;

function HexToInt(s: string): integer; // FFFFFFFF=-1
var
  i: integer;
  r, a: longword;
begin
  r:=0;
  s:=UpperCase(s);
  for i:=1 to Length(s) do begin
    if not (s[i] in ['0'..'9', 'A'..'F']) then raise Exception.Create('HexToInt error: '+s);
    if s[i] in ['0'..'9'] then a:=byte(s[i])-byte('0')
    else if s[i] in ['A'..'F'] then a:=byte(s[i])-byte('A')+10
    else a:=0;
    r:=r+(a shl ((Length(s)-i)*4));
  end;
  result:=integer(r);
end;

procedure SeparateStringByTabs(var dst: TStringArray; src: string);
var
  c: integer;
begin
  SetLength(dst, 0);
  c:=-1;
  while Pos(#9, src)>0 do begin
    Inc(c);
    SetLength(dst, c+1);
    dst[c]:=Copy(src, 1, Pos(#9, src)-1);
    Delete(src, 1, Pos(#9, src));
  end;
  if Length(src)>0 then begin
    Inc(c);
    SetLength(dst, c+1);
    dst[c]:=src;
  end;
end;

function GetDecPlacesFromStr(s: string): integer;
var
  ie, id, e: integer;
begin
  if s='' then begin
    result:=0;
  end;
  try
    ie:=Pos('e', s);
    if ie=0 then ie:=Pos('E', s);
    DecSepTo(s, '.');
    id:=Pos('.', s);
    if id=0
    then result:=0
    else begin
      if ie=0
      then result:=Length(s)-id
      else result:=ie-1-id;
    end;
    if ie>0 then begin
      e:=Round(PohStrToFloatDef(Copy(s, ie, Length(s)-ie), 0));
      result:=Max(0,result+(-e));
    end;
  except
    result:=0;
  end;
end;

function IntToStr(Value: double): string;
begin
  result:=IntToStr(Round(Value));
end;

function PohFloatToStr(d: extended): string;
begin
  result:=Format('%g', [d]);
end;

function PohFloatToStr(d: extended; decPlaces: integer): string;
begin
  result:=Format('%0.*f', [decPlaces, d]);
end;

function PohFloatToStr(d: extended; decPlaces, decPlacesMax: integer): string;
begin
  result:=PohFloatToStrEx(d, DecimalSeparator, decPlaces, decPlacesMax, 0);
end;

function PohFloatToStrEx(d: extended; decSep: char; decPlaces, decPlacesMax, maxLength: integer): string;
var
  i: integer;
begin
  if decPlacesMax<0 then decPlacesMax:=0;
  decPlaces:=Max(0, Min(decPlaces, decPlacesMax));

  result:=Format('%0.*f', [decPlacesMax, d]);
  DecSepTo(result, decSep);

  if decPlaces<decPlacesMax then begin
    i:=decPlacesMax-decPlaces;
    while (i>0) and (Length(result)>0) and (result[Length(result)]='0') do begin
      Delete(result, Length(result), 1);
      Dec(i);
    end;
  end;
  if maxLength>0 then Delete(result, maxLength+1, Length(result)-maxLength);
  if (Length(result)>0) and (result[Length(result)]=decSep) then Delete(result, Length(result), 1);
end;

function PohStrToFloat(s: string): extended;
begin
  DecSepToWinSep(s);
  if s=''
  then result:=0
  else result:=StrToFloat(s);
end;

function PohStrToFloatDef(s: string; default: extended): extended;
begin
  DecSepToWinSep(s);
  try
    result:=StrToFloat(s);
  except
    result:=default;
  end;
end;

function PohDateToString(dt: TDateTime; sepChar: string): string;
var
  year, month, day: word;
begin
  result:='';
  DecodeDate(dt, year, month, day);
  result:=Format('%.2d', [day])+sepChar+Format('%.2d', [month])+sepChar+Format('%.4d', [year]);
end;

procedure DecSepTo(var s: string; ch: char);
var
  i: integer;
begin
{$WARNINGS OFF}
  for i:=1 to Length(s) do if (s[i] in PohDecimalSeparators) or (s[i]=DecimalSeparator) then s[i]:=ch;
{$WARNINGS ON}
end;

function GetDecSepTo(s: string; ch: char): string;
begin
  DecSepTo(s, ch);
  result:=s;
end;

procedure DecSepToWinSep(var s: string);
begin
  DecSepTo(s, DecimalSeparator);
end;

end.
