------------------------------------ FIRST SCRIPT ------------------------------------

on mouseUp
  answer specialFind(msg)
end mouseUp

function specialFind string
  --
  if string is empty then
    ask "Statement :"
    if the result is cancel or it is empty then return "Cancelled"
    put it into string
  end if
  --
  set cursor to watch
  put parseStatement(string) into data
  put line 1 of data into statement   -- ex: "pain" and ( "back" or "head" )
  put line 2 of data into targetField -- ex: bg fld "text"
  --
  put filter(statement) into statement
  put makeExecutable(statement,targetField) into statement
  --
  do "mark cards where" && statement
  return the number of marked cards
  --
end specialFind

function makeExecutable statement,targetField
  repeat with x = the number of words of statement down to 1
    if word x of statement is "(" then next repeat
    if word x of statement is ")" then next repeat
    if word x of statement is "and" then next repeat
    if word x of statement is "or" then next repeat
    if word x of statement is "not" then next repeat
    put "(" & word x of statement && "is in" && targetField & ")" into word x of statement
  end repeat
  return statement
end makeExecutable

function parseStatement string
  if word 1 of string is not "find" then return "invalid command"
  if " in " is not in string then return "invalid container ref"
  delete word 1 of string
  put offset(" in ",string) into x
  put the number of chars of string into y
  put char 1 to (x-1) of string into findWhat
  put char (x+4) to y of string into findWhere
  return findWhat & return & findWhere
end parseStatement

function filter string
  put the number of chars of string into lastChar
  repeat with x = lastChar down to 1
    if char x of string is ")" then
      if char (x+1) of string is not space then put space after char x of string
      if char (x-1) of string is not space then put space before char x of string
    end if
    if char x of string is "(" then
      if char (x+1) of string is not space then put space after char x of string
      if char (x-1) of string is not space then put space before char x of string
    end if
  end repeat
  return string
end filter

------------------------------------ SECOND SCRIPT ------------------------------------

-- e.g. to navigate the found cards only, the ones that were marked by the above.
-- install this handler in the bg script of the bg(s) where cards will be found.

on arrowKey direction
  --
  put the number of marked cards into markedCards
  if markedCards < 2 then
    go to card "Search Card"
    mark all cards -- e.g. resets the navigation to "All" cards
    return empty
  end if
  --
  if (direction is left) or (direction is up) then
    go to previous marked card
  end if
  --
  if (direction is right) or (direction is down) then
    go to next marked card
  end if
  --
end arrowKey