var
  FCache1: TTntStringList;
  FCache1Vals: TTntStringList;
  FCache2: TTntStringList;
  FCache2Vals: TTntStringList;

function Initialize: Boolean;
begin
  result := True;
end;

procedure Finalize;
begin
end;

procedure BeginSort;
begin
  FCache1 := TTntStringList.Create;
  FCache1Vals := TTntStringList.Create;
  FCache2 := TTntStringList.Create;
  FCache2Vals := TTntStringList.Create;
  FCache1.Sorted := True;
  FCache2.Sorted := True;
end;

procedure EndSort;
begin
  FCache2Vals.Free;
  FCache2.Free;
  FCache1Vals.Free;
  FCache1.Free;
end;

function ExtractNumberFromFileName(AFileName: WideString): Int64;
var
  AParts: TTntStringList;
  AStr, ANumPart: WideString;
  ALen, i: Integer;
begin
  result := 0;
  ALen := Length(AFileName);
  if ALen = 0 then exit;

  AParts := TTntStringList.Create;
  try
    ANumPart := '';
    for i := 1 to ALen do
    begin
      AStr := MidStr(AFileName, i, 1);
      if (AStr <> '-') and IsValidNumberString(AStr, False, '') then
        ANumPart := ANumPart + AFileName[i]
      else if ANumPart <> '' then
      begin
        if AParts.Count > 0 then
          AParts.Insert(0, ANumPart)
        else
          AParts.Add(ANumPart);
        ANumPart := '';
      end;
    end;
    if ANumPart <> '' then
      AParts.Add(ANumPart);

    if AParts.Count > 0 then
    begin
      for i := 0 to AParts.Count - 1 do
      begin
        result := result +
                  Power(1000000, i) +
                  StrToInt(AParts.Strings[i]);
      end;
    end;
  finally
    AParts.Free;
  end;
end;

function DoCompareInt64(AInt1, AInt2: Int64): Integer;
begin
  result := 0;
  if AInt1 < AInt2 then result := -1;
  if AInt1 = AInt2 then result := 0;
  if AInt1 > AInt2 then result := 1;
end;

function Sort (AItem1, AItem2: TImageItem): Integer;
var
  AIdx: Integer;
  AVal1, AVal2: Int64;
begin
  result := 0;
  if AItem1 = AItem2 then exit;

  AIdx := FCache1.IndexOf (AItem1.GUID);
  if AIdx = -1 then
  begin
    AVal1 := ExtractNumberFromFileName(WideChangeFileExt(AItem1.FileNameOnly, ''));
    AIdx := FCache1Vals.Add (IntToStr(AVal1));
    FCache1.AddObject(AItem1.GUID, AIdx);
  end
  else
    AVal1 := StrToInt(FCache1Vals.Strings[FCache1.Objects[AIdx]]);

  AIdx := FCache2.IndexOf (AItem2.GUID);
  if AIdx = -1 then
  begin
    AVal2 := ExtractNumberFromFileName(WideChangeFileExt(AItem2.FileNameOnly, ''));
    AIdx := FCache2Vals.Add (IntToStr(AVal2));
    FCache2.AddObject(AItem2.GUID, AIdx);
  end
  else
    AVal2 := StrToInt(FCache2Vals.Strings[FCache2.Objects[AIdx]]);

  result := DoCompareInt64(AVal1, AVal2);
  if OSIs64Bit then
    result := result shl 4;
end;
