// http://akelpad.sourceforge.net/forum/viewtopic.php?p=27932#27932
// Version: 2015-03-29
// Author: KDJ
//
// *** Open next/previous/first/last file in directory of current file ***
//
// Usage:
//   Call("Scripts::Main", 1, "OpenNextFile.js", '-direction=1 -cycle=0 -ext=0 -tab=0')
//
// Arguments:
//   -direction=1  - open next file - default
//   -direction=-1 - open previous file
//   -direction=0  - open first file
//   -direction=2  - open last file
//   -cycle=0      - cycle search turn off - default
//   -cycle=1      - cycle search turn on
//   -ext=0        - open file any type (extension) - default
//   -ext=1        - open file, same type as current file
//   -tab=0        - open in current tab - default
//   -tab=1        - open in new tab
//
// Remark:
//   Files are sorted in alphabetical order.

var sEditFile = AkelPad.GetEditFile(0);

if (! sEditFile)
  WScript.Quit();

var oSys        = AkelPad.SystemFunction();
var nDirecton   = AkelPad.GetArgValue("direction", 1);
var bCycle      = AkelPad.GetArgValue("cycle", 0);
var bExt        = AkelPad.GetArgValue("ext", 0);
var bTab        = AkelPad.GetArgValue("tab", 0);
var hMainWnd    = AkelPad.GetMainWnd();
var bSingleOpen = AkelPad.SendMessage(hMainWnd, 1222 /*AKD_GETMAININFO*/, 152 /*MI_SINGLEOPENFILE*/, 0);
var sDir        = AkelPad.GetFilePath(sEditFile, 1 /*CPF_DIR*/) + "\\";
var sExt        = bExt ? AkelPad.GetFilePath(sEditFile, 4 /*CPF_FILEEXT*/) : "*";
var lpFindData  = AkelPad.MemAlloc(44 + (260 + 14) * 2); //sizeof(WIN32_FIND_DATA)
var hFindFile   = oSys.Call("Kernel32::FindFirstFileW", sDir + "*." + sExt, lpFindData);
var aFile;
var sNewFile;
var i, n;

if (hFindFile != -1 /*INVALID_HANDLE_VALUE*/);
{
  sEditFile = AkelPad.GetFilePath(sEditFile, 2 /*CPF_FILENAME*/).toUpperCase();
  aFile     = [];

  do
  {
    if (! (AkelPad.MemRead(lpFindData, 3 /*DT_DWORD*/) & 16 /*FILE_ATTRIBUTE_DIRECTORY*/))
      aFile.push(AkelPad.MemRead(_PtrAdd(lpFindData, 44 /*offsetof(WIN32_FIND_DATAW, cFileName)*/), 1 /*DT_UNICODE*/));
  }
  while (oSys.Call("Kernel32::FindNextFileW", hFindFile, lpFindData));

  oSys.Call("Kernel32::FindClose", hFindFile);

  if (aFile.length > 1)
  {
    aFile.sort(function(sA, sB)
      {
        return oSys.Call("Kernel32::lstrcmpiW", sA, sB);
      });

    n = -1;

    if (nDirecton == 0)
    {
      if (aFile[0].toUpperCase() != sEditFile)
        n = 0;
    }
    else if (nDirecton == 2)
    {
      if (aFile[aFile.length - 1].toUpperCase() != sEditFile)
        n = aFile.length - 1;
    }
    else
    {
      for (i = 0; i < aFile.length; ++i)
      {
        if (aFile[i].toUpperCase() == sEditFile)
          break;
      }

      if (nDirecton == 1)
      {
        if (i < aFile.length - 1)
          n = i + 1;
        else if (bCycle)
          n = 0;
      }
      else
      {
        if (i > 0)
          n = i - 1;
        else if (bCycle)
          n = aFile.length - 1;
      }
    }

    if (n >= 0)
    {
      sNewFile = sDir + aFile[n];

      if (AkelPad.IsMDI() && bTab)
        AkelPad.OpenFile(sNewFile);
      else if (AkelPad.Command(4324 /*IDM_WINDOW_FILECLOSE*/))
      {
        AkelPad.SendMessage(hMainWnd, 1219 /*AKD_SETMAININFO*/, 152 /*MIS_SINGLEOPENFILE*/, 0);
        AkelPad.OpenFile(sNewFile);
        AkelPad.SendMessage(hMainWnd, 1219 /*AKD_SETMAININFO*/, 152 /*MIS_SINGLEOPENFILE*/, bSingleOpen);
      }
    }
  }
}

AkelPad.MemFree(lpFindData);
