<?php
// $Id$


/**
 * Returns a list of the programs available on the system
 *
 * @return 
 *   An associative array with the name as the key, include file as the value.
 */
function mapi_program_list() {
  return mapi_invoke_programs('list');
}

/**
 *  Returns a valid path for the program, suggested by the hook_mapi_programs
 */
function mapi_program_path($program) {
  $paths = mapi_invoke_programs('path', $program);
  // possibility of searching paths for valid path
  if (is_array($paths)) {
    foreach ($paths as $path) {
      if (is_string($path) && is_file($path)) {
        return $path;
      }
    }
  }
  // otherwise a string could suffix for possible location
  elseif (is_string($paths) && is_file($paths)) {
    return $paths;
  }
  return FALSE;
}

/**
 *  Gets the extensions that the program can handle
 */
function mapi_program_extensions($program) {
  $exts = mapi_invoke_programs('list', $program);
  if (is_array($exts)) {
    return $exts;
  }
  return array();
}

/**
 *  Loads the details for the program
 */
function mapi_program_load($program) {
  $details = db_fetch_object(db_query("SELECT path, settings FROM {mapi_programs} WHERE name='%s'", $program));
  // if nothing already set, attempt to locate
  if (!$details->path) {
    $path = mapi_program_path($program);
    // only change it when there is something to change to.
    if ($path) {
      $details->path = $path;
    }
  }  
  return $details; 
}

/**
 *  Updates the details for the program
 */
function mapi_program_update($program, $path, $settings) {
  // update
  if (db_result(db_query("SELECT name FROM {mapi_programs} WHERE name='%s'", $program)) == $program) {
    db_query("UPDATE {mapi_programs} SET path='%s', settings='%s' WHERE name='%s'", $path, serialize($settings), $program);
  } 
  // save settings
  else {
    db_query("INSERT {mapi_programs} (name, path, settings) VALUES ('%s', '%s', '%s')", $program, $path, serialize($settings));
  }
}


function mapi_program_execute($program, $cmdline, $wait = TRUE, $refresh = FALSE) {
  // check that program is available
  $programs = mapi_program_list();
  if (!array_key_exists($program, $programs)) {
    return FALSE;
  }
  
  // load the details from the database, including possible suggestion of path
  $details = mapi_program_load($program);
  
  // file has to exist
  if (!is_file($details->path)) {
    return FALSE;
  }
  
  // attempts to put the path in an executable state for the operating system.
  $path = escapeshellarg($details->path);
  
  // can pass a simple string cmdline
  if (is_string($cmdline)) {
    $cmdline = escapeshellcmd($cmdline);
  }
  // or a nicely created array
  elseif (is_array($cmdline)) {
    foreach ($cmdline as $key => $value) {
      // has to be string
      if (!is_string($value)) {
        return false;
      }
      // only place it in string if there exist spaces in the option
      if (strpos($value, ' ') !== false) {
        $value = '"'. str_replace('"', '\\"', $value) .'"';
      }
      $cmdline[$key] = $value;
    }
    $cmdline = implode(' ', $cmdline);
  }
  // otherwise totally ignore the whole process
  else {
    return FALSE;
  }
  
  // final creation of the cmdline
  $cmdline = $path . ($cmdline ? ' '. $cmdline : '');

  // this waits for the result to finish
  // and diverts the information into a null device.
  // NEEDS WORK: Could allow for the file contents to be retrieved
  // by simply writing to a temporary file, getting those details,
  // and providing them for the process to use.
  $result = shell_exec($cmdline .' 2>&1');
  
  // return the result of the operation.
  return $result;
}

function mapi_program_installed($program) {
  // check that it is a program that exists
  $programs = mapi_program_list();
  if (!array_key_exists($program, $programs)) {
    return FALSE;
  }

  // load database details, include possible of auto-seek path.
  $details = mapi_program_load($program);
  
  // must be a file in order to be executable.
  if (is_file($details->path)) {
    return TRUE;
  }
  
  return TRUE;  
}
