--- inc/imce.page.inc	2010-11-01 09:21:41.000000000 -0400
+++ inc/imce.page.inc	2010-10-28 16:09:04.000000000 -0400
@@ -1,1103 +1,1104 @@
-<?php
-// $Id: imce.page.inc,v 1.1 2010/08/31 16:36:44 c0aslm1 Exp $
-
-/**
- * @file
- * Implements the file browser.
- */
-
-/**
- * q = imce.
- */
-function imce() {
-  module_invoke('admin_menu', 'suppress');//suppress admin_menu
-  $jsop = isset($_GET['jsop']) ? $_GET['jsop'] : NULL;
-  print imce_page($GLOBALS['user'], $jsop);
-  exit();
-}
-
-/**
- * q = user/x/imce.
- */
-function imce_user_page($account) {
-  return theme('imce_user_page', $account);
-}
-
-/**
- * Returns the imce page for the specified user.
- */
-function imce_page($user, $jsop = NULL) {
-  return theme('imce_page', imce_content($user, $jsop));
-}
-
-/**
- * Returns the content of the file browser.
- */
-function imce_content($user, $jsop = NULL) {
-
-  //execute ajax calls.
-  if ($jsop) {
-    return imce_js($user, $jsop);
-  }
-
-  //initiate configuration profile
-  if (!$imce = imce_initiate_profile($user)) {
-    return '';
-  }
-  imce_process_profile($imce);//get active directory content
-
-  //Before creating the content let's add main files required for imce to function properly.
-  $path = drupal_get_path('module', 'imce');
-  drupal_add_js($path . '/js/jquery.form.js');
-  drupal_add_js($path . '/js/imce.js');
-  drupal_add_js($path . '/js/imce_extras.js');
-  drupal_add_css($path . '/css/imce-content.css');
-
-  //process forms.
-  //reference imce inside an array so it will stay referenced during argument copy of drupal_get_form
-  $imce_ref = array('imce' => &$imce);
-  $forms = '';
-
-  if (!$imce['error']) {
-    //process file upload.
-    if (imce_perm_exists($imce, 'upload')) {
-      $forms .= drupal_get_form('imce_upload_form', $imce_ref);
-    }
-    //process file operations.
-    $forms .= drupal_get_form('imce_fileop_form', $imce_ref);
-  }
-
-  //run custom content functions. possible to insert extra forms. content is invisible when js is enabled.
-  foreach (variable_get('imce_custom_content', array()) as $func => $state) {
-    if ($state && function_exists($func) && $output = $func($imce)) {
-      $forms .= $output;
-    }
-  }
-
-  $content = theme('imce_content', imce_create_tree($imce), $forms, $imce_ref);
-
-  //make necessary changes for js conversion
-  $imce['dir'] = str_replace('%2F', '/', rawurlencode($imce['dir']));
-  unset($imce['files'], $imce['name'], $imce['directories'], $imce['subdirectories'], $imce['filesize'], $imce['quota'], $imce['tuquota'], $imce['thumbnails'], $imce['uid'], $imce['usertab']);
-
-  drupal_add_js($imce_ref, 'setting');
-
-  return $content;
-}
-
-/**
- * Ajax operations. q=imce&jsop={op}
- */
-function imce_js($user, $jsop = '') {
-  $response = array();
-
-  //data
-  if ($imce = imce_initiate_profile($user)) {
-    imce_process_profile($imce);
-    if (!$imce['error']) {
-      module_load_include('inc', 'imce', 'inc/imce.js');
-      if (function_exists($func = 'imce_js_'. $jsop)) {
-        $response['data'] = $func($imce);
-      }
-    }
-  }
-  //messages
-  $response['messages'] = drupal_get_messages();
-
-  //disable devel log.
-  $GLOBALS['devel_shutdown'] = FALSE;
-  //for upload we must return plain text header.
-  drupal_set_header('Content-Type: text/'. ($jsop == 'upload' ? 'html' : 'javascript') .'; charset=utf-8');
-  print drupal_to_js($response);
-  exit();
-}
-
-/**
- * Upload form.
- */
-function imce_upload_form(&$form_state, $ref) {
-  $imce =& $ref['imce'];
-  $form['imce'] = array(
-    '#type' => 'file',
-    '#title' => t('File'),
-    '#size' => 30,
-  );
-  if (!empty($imce['thumbnails'])) {
-    $form['thumbnails'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Create thumbnails'),
-      '#options' => imce_thumbnail_options($imce['thumbnails']),
-    );
-  }
-  $form['upload'] = array(
-    '#type' => 'submit',
-    '#value' => t('Upload'),
-    '#submit' => $imce['perm']['upload'] ? array('imce_upload_submit') : NULL,
-  );
-  $form = array('fset_upload' => array('#type' => 'fieldset', '#title' => t('Upload file')) + $form);
-  $form['#attributes']['enctype'] = 'multipart/form-data';
-  $form['#action'] = $imce['url'];
-  return $form;
-}
-
-/**
- * File operations form.
- */
-function imce_fileop_form(&$form_state, $ref) {
-  $imce =& $ref['imce'];
-  $form['filenames'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Selected files'),
-    '#maxlength' => $imce['filenum'] ? $imce['filenum']*255 : NULL,
-  );
-
-  //thumbnail
-  if (!empty($imce['thumbnails']) && imce_perm_exists($imce, 'thumb')) {
-    $form['fset_thumb'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Thumbnails'),
-    ) + imce_thumb_form($imce);
-  }
-
-  //delete
-  if (imce_perm_exists($imce, 'delete')) {
-    $form['fset_delete'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Delete'),
-    ) + imce_delete_form($imce);
-  }
-
-  //resize
-  if (imce_perm_exists($imce, 'resize')) {
-    $form['fset_resize'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Resize'),
-    ) + imce_resize_form($imce);
-  }
- 
-  $form['#action'] = $imce['url'];
-  return $form;
-}
-
-/**
- * Thumbnail form.
- */
-function imce_thumb_form(&$imce) {
-  $form['thumbnails'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Thumbnails'),
-    '#options' => imce_thumbnail_options($imce['thumbnails']),
-  );
-  $form['thumb'] = array(
-    '#type' => 'submit',
-    '#value' => t('Create thumbnails'),
-    '#submit' => $imce['perm']['thumb'] ? array('imce_thumb_submit') : NULL,
-  );
-  return $form;
-}
-
-/**
- * Delete form.
- */
-function imce_delete_form(&$imce) {
-  $form['delete'] = array(
-    '#type' => 'submit',
-    '#value' => t('Delete'),
-    '#submit' => $imce['perm']['delete'] ? array('imce_delete_submit') : NULL,
-  );
-  return $form;
-}
-
-/**
- * Resizing form.
- */
-function imce_resize_form(&$imce) {
-  $form['width'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Width x Height'),
-    '#size' => 5,
-    '#maxlength' => 4,
-    '#prefix' => '<div class="container-inline">',
-  );
-  $form['height'] = array(
-    '#type' => 'textfield',
-    '#size' => 5,
-    '#maxlength' => 4,
-    '#prefix' => 'x',
-  );
-  $form['resize'] = array(
-    '#type' => 'submit',
-    '#value' => t('Resize'),
-    '#submit' => $imce['perm']['resize'] ? array('imce_resize_submit') : NULL,//permission for submission
-    '#suffix' => '</div>',
-  );
-  $form['copy'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Create a new image'),
-    '#default_value' => 1,
-  );
-  return $form;
-}
-
-/**
- * Validate file operations form.
- */
-function imce_fileop_form_validate($form, &$form_state) {
-  $imce =& $form['#parameters'][2]['imce'];
-
-  //check if the filenames is empty
-  if ($form_state['values']['filenames'] == '') {
-    return form_error($form['filenames'], t('Please select a file.'));
-  }
-
-  //filenames come seperated by colon
-  $filenames = explode(':', $form_state['values']['filenames']);
-  $cnt = count($filenames);
-  //check the number of files.
-  if ($imce['filenum'] && $cnt > $imce['filenum']) {
-    return form_error($form['filenames'], t('You are not allowed to operate on more than %num files.', array('%num' => $imce['filenum'])));
-  }
-
-  //check if there is any illegal choice
-  for ($i = 0; $i < $cnt; $i++) {
-    $filenames[$i] = $filename = rawurldecode($filenames[$i]);
-    if (!isset($imce['files'][$filename])) {
-      watchdog('imce', 'Illegal choice %choice in !name element.', array('%choice' => $filename, '!name' => t('directory (%dir)', array('%dir' => file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir'])))), WATCHDOG_ERROR);
-      return form_error($form['filenames'], t('An illegal choice has been detected. Please contact the site administrator.'));
-    }
-  }
-
-  $form_state['values']['filenames'] = $filenames;
-}
-
-/**
- * Submit upload form.
- */
-function imce_upload_submit($form, &$form_state) {
-  $form_state['redirect'] = FALSE;
-  $imce =& $form['#parameters'][2]['imce'];
-  $validators = array('imce_validate_all' => array(&$imce));
-  $dirpath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']);
-
-  //save uploaded file.
-  $replace = variable_get('imce_settings_replace', FILE_EXISTS_RENAME);
-  if ($file = file_save_upload('imce', $validators, $dirpath, $replace)) {
-
-    //core bug #203204.
-    @chmod($file->filepath, 0664);
-
-    //core bug #54223.
-    if ($replace == FILE_EXISTS_RENAME) {
-      $name = basename($file->filepath);
-      if ($name != $file->filename) {
-        $file->filename = $name;
-        drupal_set_message(t('The file has been renamed to %filename.', array('%filename' => $file->filename)));
-      }
-    }
-    elseif ($replace == FILE_EXISTS_REPLACE) {//check duplicates
-      if ($_file = db_fetch_object(db_query("SELECT fid FROM {files} WHERE filepath = '%s' AND fid <> %d", $file->filepath, $file->fid))) {
-        db_query("DELETE FROM {files} WHERE fid = %d", $file->fid);
-        $file->fid = $_file->fid;
-      }
-    }
-
-    $file->uid = $imce['uid'];//global user may not be the owner.
-    $file->status = FILE_STATUS_PERMANENT;//make permanent
-    drupal_write_record('files', $file, array('fid'));//update
-    imce_file_register($file);
-    drupal_set_message(t('%filename has been uploaded.', array('%filename' => $file->filename)));
-
-    //update file list
-    $img = imce_image_info($file->filepath);
-    $file->width = $img ? $img['width'] : 0;
-    $file->height = $img ? $img['height'] : 0;
-    imce_add_file($file, $imce);
-
-    //create thumbnails
-    if (isset($form_state['values']['thumbnails']) && $img) {
-      imce_create_thumbnails($file->filename, $imce, $form_state['values']['thumbnails']);
-    }
-  }
-  else {
-    drupal_set_message(t('Upload failed.'), 'error');
-  }
-}
-
-/**
- * Submit thumbnail form.
- */
-function imce_thumb_submit($form, &$form_state) {
-  $form_state['redirect'] = FALSE;
-  $imce =& $form['#parameters'][2]['imce'];
-  //create thumbnails
-  imce_process_files($form_state['values']['filenames'], $imce, 'imce_create_thumbnails', array($form_state['values']['thumbnails']));
-}
-
-/**
- * Submit delete form.
- */
-function imce_delete_submit($form, &$form_state) {
-  $form_state['redirect'] = FALSE;
-  $imce =& $form['#parameters'][2]['imce'];
-
-  $deleted = imce_process_files($form_state['values']['filenames'], $imce, 'imce_delete_file');
-
-  if (!empty($deleted)) {
-    drupal_set_message(t('File deletion successful: %files.', array('%files' => utf8_encode(implode(', ', $deleted)))));
-  }
-
-}
-
-/**
- * Submit resize form.
- */
-function imce_resize_submit($form, &$form_state) {
-  $form_state['redirect'] = FALSE;
-  $imce =& $form['#parameters'][2]['imce'];
-
-  //check dimensions
-  $width = (int) $form_state['values']['width'];
-  $height = (int) $form_state['values']['height'];
-  list($maxw, $maxh) = explode('x', $imce['dimensions']);
-  if ($width < 1 || $height < 1 || ($maxw && ($width > $maxw || $height > $maxh))) {
-    drupal_set_message(t('Please specify dimensions within the allowed range that is from 1x1 to @dimensions.', array('@dimensions' => $imce['dimensions'] ? $imce['dimensions'] : t('unlimited'))), 'error');
-    return;
-  }
-
-  $resized = imce_process_files($form_state['values']['filenames'], $imce, 'imce_resize_image', array($width, $height, $form_state['values']['copy']));
-
-  if (!empty($resized)) {
-    drupal_set_message(t('File resizing successful: %files.', array('%files' => utf8_encode(implode(', ', $resized)))));
-  }
-
-}
-
-/**
- * Do batch operations on files.
- * Used by delete, resize, create thumbnail submissions.
- */
-function imce_process_files($filenames, &$imce, $function, $args = array()) {
-  $args = array_merge(array('', &$imce), $args);
-  $processed = array();
-
-  foreach ($filenames as $filename) {
-    $args[0] = $filename;
-    if (call_user_func_array($function, $args)) {
-      $processed[] = $filename;
-    }
-  }
-
-  return $processed;
-}
-
-/**
- * Delete a file in the file list.
- */
-function imce_delete_file($filename, &$imce) {
-  $filepath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']) .'/'. $filename;
-  if (!imce_delete_filepath($filepath)) {
-    return FALSE;
-  }
-  imce_remove_file($filename, $imce);
-  return TRUE;
-}
-
-/**
- * Delete a file by path.
- */
-function imce_delete_filepath($filepath) {
-  $file = db_fetch_object(db_query("SELECT * FROM {files} WHERE filepath = '%s'", $filepath));
-
-  //file exists in database
-  if ($file) {
-    //prevent imce returning ref count
-    $file->imce_noref = TRUE;
-    //check references
-    $refs = array_filter(module_invoke_all('file_references', $file));
-    //file is in use
-    if (!empty($refs)) {
-      drupal_set_message(t('%filename is in use by another application.', array('%filename' => $file->filename)), 'error');
-      return FALSE;
-    }
-    //prepare deletion
-    module_invoke_all('file_delete', $file);
-    if (!file_delete($file->filepath)) {
-      return FALSE;
-    }
-    db_query('DELETE FROM {files} WHERE fid = %d', $file->fid);
-  }
-  //not in db. probably loaded via ftp.
-  elseif (!file_delete($filepath)) {
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-/**
- * Create all selected thumbnails.
- */
-function imce_create_thumbnails($filename, &$imce, $values) {
-  $created = array();
-  foreach ($imce['thumbnails'] as $thumbnail) {
-    if ($values[$thumbnail['name']] && imce_create_thumbnail($filename, $imce, $thumbnail)) {
-      $created[] = $thumbnail['name'];
-    }
-  }
-  if (!empty($created)) {
-  drupal_set_message(t('Thumbnail creation (%thumbnames) successful for %filename.', array('%thumbnames' => implode(', ', $created), '%filename' => utf8_encode($filename))));
-  }
-  return $created;
-}
-
-/**
- * Create a thumbnail.
- */
-function imce_create_thumbnail($filename, &$imce, $thumbnail) {
-  //generate thumbnail name
-  $name = $thumbnail['prefix'];
-  if ($thumbnail['suffix'] != '' && $dot = strrpos($filename, '.')) {
-    $name .= substr($filename, 0, $dot);
-    $name .= $thumbnail['suffix'];
-    $name .= substr($filename, $dot);
-  }
-  else {
-    $name .= $filename;
-  }
-  //scale the image
-  list($width, $height) = explode('x', $thumbnail['dimensions']);
-  return imce_resize_image($filename, $imce, $width, $height, TRUE, $name, variable_get('imce_settings_thumb_method', 'scale_and_crop'));
-}
-
-/**
- * Resize an image in the file list. Also used for thumbnail creation.
- */
-function imce_resize_image($filename, &$imce, $width, $height, $copy = TRUE, $dest = FALSE, $op = 'resize') {
-  $dirpath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']);
-  $filepath = $dirpath .'/'. $filename;
-
-  //check if the file is an image
-  if (!$imce['files'][$filename]['width'] || !$img = imce_image_info($filepath)) {
-    drupal_set_message(t('%filename is not an image.', array('%filename' => utf8_encode($filename))), 'error', FALSE);
-    return FALSE;
-  }
-
-  if (substr($op, 0, 5) == 'scale' && !($width < $img['width'] || $height < $img['height'])) {
-    drupal_set_message(t('Scaling up is not allowed.'), 'error', FALSE);
-    return FALSE;
-  }
-
-  //create file object
-  $file = new stdClass();
-  $file->filepath = $dirpath .'/'. $dest;
-  if (!$dest || $dest == $filename) {
-    $file->filepath = $copy ? file_create_filename($filename, $dirpath) : $filepath;
-  }
-  $file->filename = basename($file->filepath);
-
-  //check if a file having the same properties exists already.
-  if (isset($imce['files'][$file->filename])) {
-    if (($f = $imce['files'][$file->filename]) && $f['width'] == $width && $f['height'] == $height) {
-      drupal_set_message(t('%filename(%dimensions) already exists.', array('%filename' => utf8_encode($file->filename), '%dimensions' => $width .'x'. $height)), 'error');
-      return FALSE;
-    }
-  }
-
-  //validate file name
-  $errors = file_validate_name_length($file);
-  if (!empty($errors)) {
-    drupal_set_message($errors[0], 'error');
-    return FALSE;
-  }
-
-  //resize image to a temp file
-  $temp = tempnam(realpath(file_directory_temp()), 'imc');
-  register_shutdown_function('file_delete', $temp);
-  $function = 'image_'. $op;
-  if (!$function($filepath, $temp, $width, $height)) {
-    drupal_set_message(t('%filename cannot be resized to %dimensions', array('%filename' => utf8_encode($filename), '%dimensions' => $width .'x'. $height)), 'error', FALSE);
-    return FALSE;
-  }
-
-  //validate quota
-  $file->filesize = filesize($temp);
-  $overwrite = $file->filename == $filename;
-  if (!imce_validate_quotas($file, $imce, $overwrite ? -$imce['files'][$filename]['size'] : 0)) {
-    return FALSE;
-  }
-
-  //copy from temp to filepath
-  if (!@copy($temp, $file->filepath)) {
-    drupal_set_message(t('The selected file %file could not be copied.', array('%file' => utf8_encode($file->filename))), 'error', FALSE);
-    return FALSE;
-  }
-  @chmod($file->filepath, 0664);
-
-  //build the rest of the file object
-  $file->uid = $imce['uid'];
-  $file->filemime = $img['mime'];
-  $file->status = FILE_STATUS_PERMANENT;
-  $file->timestamp = time();
-
-  //if we are overwriting the file and it is already in database.
-  $update = array();
-  if ($overwrite && $_file = db_fetch_object(db_query("SELECT f.* FROM {files} f WHERE f.filepath = '%s'", $file->filepath))) {
-    $file->fid = $_file->fid;
-    $file->uid = $_file->uid;
-    $update[] = 'fid';
-  }
-
-  //save the file
-  drupal_write_record('files', $file, $update);
-  imce_file_register($file);
-
-  //update file list
-  //if the file was scaled get the new dimensions
-  if ($op == 'scale') {
-    $img = imce_image_info($file->filepath);
-    $width = $img['width'];
-    $height = $img['height'];
-  }
-  $file->width = $width;
-  $file->height = $height;
-  imce_add_file($file, $imce);
-
-  return $file;
-}
-
-/**
- * Add a new file to the file list.
- */
-function imce_add_file($file, &$imce) {
-  $imce['dirsize'] += $file->filesize;
-  if (isset($imce['files'][$file->filename])) {
-    $imce['dirsize'] -= $imce['files'][$file->filename]['size'];
-  }
-  $imce['files'][$file->filename] = array(
-    'name' => $file->filename,
-    'size' => $file->filesize,
-    'width' => $file->width,
-    'height' => $file->height,
-    'date' => $file->timestamp
-  );
-  if (isset($_GET['jsop'])) {
-    $add = $imce['files'][$file->filename];
-    $add['name'] = rawurlencode($file->filename);
-    $add['fsize'] = format_size($file->filesize);
-    $add['fdate'] = format_date($file->timestamp, 'small');
-    $add['id'] = $file->fid;
-    $imce['added'][] = $add;
-  }
-}
-
-/**
- * Remove a file from the file list.
- */
-function imce_remove_file($filename, &$imce) {
-  if (isset($imce['files'][$filename])) {
-    $imce['dirsize'] -= $imce['files'][$filename]['size'];
-    unset($imce['files'][$filename]);
-    if (isset($_GET['jsop'])) {
-      $imce['removed'][] = rawurlencode($filename);
-    }
-  }
-}
-
-/**
- * Validate uploaded file.
- */
-function imce_validate_all(&$file, $imce) {
-
-  //fix FILE_EXISTS_ERROR bug. core bug #54223.
-  if (!$file->destination && variable_get('imce_settings_replace', FILE_EXISTS_RENAME) == FILE_EXISTS_ERROR) {
-    return array(t('File browser is set to reject the upload of existing files.'));
-  }
-
-  //validate image resolution only if filesize validation passes.
-  //because user might have uploaded a very big image
-  //and scaling it may exploit system memory.
-  $errors = imce_validate_filesize($file, $imce['filesize']);
-  //image resolution validation
-  if (empty($errors)) {
-    $errors = array_merge($errors, file_validate_image_resolution($file, $imce['dimensions']));
-  }
-  //directory quota validation
-  if ($imce['quota']) {
-    $errors = array_merge($errors, imce_validate_quota($file, $imce['quota'], $imce['dirsize']));
-  }
-  //file extension validation
-  if ($imce['extensions'] != '*') {
-    $errors = array_merge($errors, file_validate_extensions($file, $imce['extensions']));
-  }
-  //user quota validation. check it if no errors were thrown.
-  if (empty($errors) && $imce['tuquota']) {
-    $errors = imce_validate_tuquota($file, $imce['tuquota'], file_space_used($imce['uid']));
-  }
-  return $errors;
-}
-
-/**
- * Validate filesize for maximum allowed file size.
- */
-function imce_validate_filesize($file, $maxsize = 0) {
-  $errors = array();
-  if ($maxsize && $file->filesize > $maxsize) {
-    $errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($file->filesize), '%maxsize' => format_size($maxsize)));
-  }
-  return $errors;
-}
-
-/**
- * Validate filesize for directory quota.
- */
-function imce_validate_quota($file, $quota = 0, $currentsize = 0) {
-  $errors = array();
-  if ($quota && ($currentsize + $file->filesize) > $quota) {
-    $errors[] = t('%filename is %filesize which would exceed your directory quota. You are currently using %size of %total_quota.', array('%size' => format_size($currentsize), '%total_quota' => format_size($quota), '%filesize' => format_size($file->filesize), '%filename' => utf8_encode($file->filename)));
-  }
-  return $errors;
-}
-
-/**
- * Validate filesize for total user quota.
- */
-function imce_validate_tuquota($file, $quota = 0, $currentsize = 0) {
-  $errors = array();
-  if ($quota && ($currentsize + $file->filesize) > $quota) {
-    $errors[] = t('%filename is %filesize which would exceed your total user quota. You are currently using %size of %total_quota.', array('%size' => format_size($currentsize), '%total_quota' => format_size($quota), '%filesize' => format_size($file->filesize), '%filename' => utf8_encode($file->filename)));
-  }
-  return $errors;
-}
-
-/**
- * Validate both directory and total user quota. Returns true/false not errors.
- */
-function imce_validate_quotas($file, &$imce, $add = 0) {
-  $errors = imce_validate_quota($file, $imce['quota'], $imce['dirsize'] + $add);
-  if (empty($errors) && $imce['tuquota']) {
-    $errors = imce_validate_tuquota($file, $imce['tuquota'], file_space_used($imce['uid']) + $add);
-  }
-  if (!empty($errors)) {
-    drupal_set_message($errors[0], 'error');
-    return FALSE;
-  }
-  return TRUE;
-}
-
-/**
- * Check if the file is an image and return info.
- */
-function imce_image_info($file) {
-  if (is_file($file) && ($dot = strrpos($file, '.')) && in_array(strtolower(substr($file, $dot+1)), array('jpg', 'jpeg', 'gif', 'png')) && ($info = @getimagesize($file)) && in_array($info[2], array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG)) ) {
-    return array('width' => $info[0], 'height' => $info[1], 'type' => $info[2], 'mime' => $info['mime']);
-  }
-  return FALSE;
-}
-
-/**
- * Return thumbnails as options to be used in upload form.
- */
-function imce_thumbnail_options($thumbs = array()) {
-  $options = array();
-  foreach ($thumbs as $thumb) {
-    $options[$thumb['name']] = $thumb['name'] .' ('. $thumb['dimensions'] .')';
-  }
-  return $options;
-}
-
-/**
- * Initiate and return configuration profile for the $user.
- */
-function imce_initiate_profile($user) {
-
-  //check user profile and translate tokens in directory paths and evaluate php paths.
-  if ($imce = imce_user_profile($user)) {
-    imce_process_directories($imce, $user);
-    if (!empty($imce['directories'])) {
-      $imce['uid'] = (int) $user->uid;
-      $imce['url'] = url($_GET['q']);
-      $imce['clean'] = variable_get('clean_url', 0) == 1;
-      $imce['absurls'] = variable_get('imce_settings_absurls', 0) == 1;
-      $imce['furl'] = file_create_url('');
-      $imce['filesize'] *= 1048576;//convert from Mb to byte
-      $imce['quota'] *= 1048576;
-      $imce['tuquota'] *= 1048576;
-      $imce['filenum'] = (int) $imce['filenum'];
-      //check and set the active directory
-      if ($info = imce_working_directory($imce)) {
-        $imce['direct'] = isset($imce['directories'][$info['name']]);
-        $imce['directories'][$info['name']] = $info;
-        $imce['dir'] = $info['name'];
-        $imce['perm'] = $info;//copy permissions of the active directory.
-        unset($imce['perm']['name']);
-      }
-      else {
-        drupal_set_message(t('Unable to get a working directory for the file browser!'), 'error');
-        $imce['dir'] = FALSE;
-        $imce['error'] = TRUE;
-      }
-      return $imce;
-    }
-    drupal_set_message(t('There is no valid directory specified for the file browser!'), 'error');
-  }
-  else {
-    drupal_set_message(t('You do not have access to any configuration profile to use the file browser!'), 'error');
-  }
-
-  return FALSE;
-}
-
-/**
- * Get files and folders of the actve directory. Do custom processing.
- */
-function imce_process_profile(&$imce) {
-  //get directory content. do a custom scan if it is set
-  $scan = ($scan = variable_get('imce_custom_scan', '')) && function_exists($scan) ? $scan : 'imce_scan_directory';
-  $imce += $scan($imce['dir'], $imce);
-
-  //run custom process functions
-  foreach (variable_get('imce_custom_process', array()) as $func => $state) {
-    if ($state && function_exists($func)) {
-      $func($imce);
-    }
-  }
-
-  //set subdirectories
-  if (!$imce['error'] && !imce_subdirectories_accessible($imce)) {
-    $imce['subdirectories'] = array();
-  }
-}
-
-/**
- * Translate tokens and evaluate php in directory names.
- * Convert directories into an associative array (dirname => info)
- */
-function imce_process_directories(&$imce, $user) {
-  $directories = $imce['directories'];
-  $paths = array();
-  $translate = array('%uid' => $user->uid);
-
-  foreach ($directories as $directory) {
-    if (substr($directory['name'], 0, 4) == 'php:') {
-      $directory['name'] = eval(substr($directory['name'], 4));
-     //php may return an array of directories
-      if (is_array($directory['name'])) {
-        foreach ($directory['name'] as $name) {
-          $paths[$name] = array('name' => $name) + $directory;
-        }
-        continue;
-      }
-    }
-    else {
-      $directory['name'] = strtr($directory['name'], $translate);
-    }
-    if ($directory['name']) {
-      $paths[$directory['name']] = $directory;
-    }
-  }
-
-  $imce['directories'] = $paths;
-}
-
-/**
- * Return an avaliable directory for the profile.
- */
-function imce_working_directory(&$imce) {
-  //Do not use session if there is only one directory assigned.
-  $sess = TRUE;
-  if (count($imce['directories']) < 2) {
-    $perms = reset($imce['directories']);
-    if (!isset($perms['subnav']) || !$perms['subnav']) {
-      $sess = FALSE;
-    }
-  }
-  //check GET.
-  if (isset($_GET['dir'])) {
-    if ($info = imce_directory_info($_GET['dir'], $imce)) {
-      if (imce_check_directory($_GET['dir'], $imce)) {
-        if ($sess) {
-          $_SESSION['imce_directory'] = rawurlencode($info['name']);
-        }
-      }
-      else {
-        $info = FALSE;
-      }
-    }
-    else {
-      imce_inaccessible_directory($_GET['dir'], $imce);
-    }
-    return $info;
-  }
-
-  //check session
-  if ($sess && isset($_SESSION['imce_directory'])) {
-    $dirname = rawurldecode($_SESSION['imce_directory']);
-    if ($info = imce_directory_info($dirname, $imce)) {
-      if (imce_check_directory($dirname, $imce)) {
-        return $info;
-      }
-    }
-  }
-
-  //or the whole list.
-  foreach ($imce['directories'] as $dirname => $info) {
-    if (imce_check_directory($dirname, $imce)) {
-      if ($sess) {
-        $_SESSION['imce_directory'] = rawurlencode($dirname);
-      }
-      return $info;
-    }
-  }
-
-  return FALSE;
-}
-
-/**
- * Create a writable directory(any level) under file system directory.
- */
-function imce_check_directory($dirname, $imce = array()) {
-
-  $root = file_directory_path();
-  $dirpath = $root .'/'. $dirname;
-
-  if (!file_check_directory($dirpath)) {//directory does not exist. try to create it.
-    $path = $root;
-    foreach (explode('/', $dirname) as $arg) {
-      $path .= '/'. $arg;
-      if (!file_check_location($path, $root) || !file_check_directory($path, FILE_CREATE_DIRECTORY)) {
-        return imce_inaccessible_directory($dirname, $imce);
-      }
-    }
-  }
-  elseif (!file_check_location($dirpath, $root)) {//directory exists outside of root.
-    return imce_inaccessible_directory($dirname, $imce);
-  }
-
-  return TRUE;
-}
-
-/**
- * Generate and log a directory access error.
- */
-function imce_inaccessible_directory($dirname, $imce = array()) {
-  if (is_string($dirname)) {
-    $dirname = utf8_encode($dirname);
-    drupal_set_message(t('Directory %dirname is not accessible.', array('%dirname' => $dirname)), 'error');
-    watchdog('imce', 'Access to %directory was denied.', array('%directory' => $dirname), WATCHDOG_ERROR);
-  }
-  return FALSE;
-}
-
-/**
- * Return the permissions for a directory that is accessed directly or indirectly.
- * A child of a predefined directory in the directory list takes its parent's properties.
- * If it has multiple parents, it gets the properties of the latter in the list.
- */
-function imce_directory_info($dirname, $imce) {
-
-  if (isset($imce['directories'][$dirname])) {
-    return $imce['directories'][$dirname];
-  }
-
-  $info = FALSE;
-  $root = file_directory_path();
-  $dirpath = $root .'/'. $dirname;
-  if (imce_reg_dir($dirname) && file_check_directory($dirpath)) {
-    foreach ($imce['directories'] as $name => $prop) {
-      if ($prop['subnav'] && file_check_location($dirpath, $root .'/'. $name)) {
-        $info = $prop;
-        $info['name'] = $dirname;
-      }
-    }
-  }
-
-  return $info;
-}
-
-/**
- * Detect if the subdirectories are accessible through any directory(not just the current one) in the list.
- */
-function imce_subdirectories_accessible(&$imce) {
-
-  if (!empty($imce['subdirectories'])) {
-    $root = file_directory_path() .'/';
-    //checking only the first one is sufficient.
-    $dirname = ($imce['dir'] == '.' ? '' : $imce['dir'] .'/') . $imce['subdirectories'][0];
-    $dirpath = $root . $dirname;
-
-    //check if any setting is applicable for this subdirectory through any directory in the list.
-    foreach ($imce['directories'] as $name => $info) {
-      if ($info['subnav'] && $dirname != $name && file_check_location($dirpath, $root . $name)) {
-        return TRUE;
-      }
-    }
-  }
-
-  return FALSE;
-}
-
-/**
- * Check if a permission is given to at least one directory in the list.
- */
-function imce_perm_exists(&$imce, $perm) {
-  static $perms = array();
-
-  if (isset($perms[$perm])) {
-    return $perms[$perm];
-  }
-
-  if (isset($imce['perm'][$perm]) && $imce['perm'][$perm]) {
-    return $perms[$perm] = TRUE;
-  }
-
-  foreach ($imce['directories'] as $name => $info) {
-    if (isset($info[$perm]) && $info[$perm]) {
-      return $perms[$perm] = TRUE;
-    }
-  }
-
-  return $perms[$perm] = FALSE;
-}
-
-/**
- * Scan directory and return file list, subdirectories, and total size.
- */
-function imce_scan_directory($dirname, $imce = array()) {
-
-  $directory = array('dirsize' => 0, 'files' => array(), 'subdirectories' => array(), 'error' => FALSE);
-  $dirpath = file_directory_path() .'/'. $dirname;
-
-  if (!is_string($dirname) || $dirname == '' || !$handle = opendir($dirpath)) {
-    imce_inaccessible_directory($dirname, $imce);
-    $directory['error'] = TRUE;
-    return $directory;
-  }
-
-  $exclude = array('.' => 1, '..' => 1, 'CVS' => 1, '.svn' => 1, '.htaccess' => 1);
-  while (($file = readdir($handle)) !== FALSE) {
-    if (isset($exclude[$file])) {
-      continue;
-    }
-
-    $path = $dirpath .'/'. $file;
-
-    if (is_dir($path)) {
-      $directory['subdirectories'][] = $file;
-      continue;
-    }
-
-    $width = $height = 0;
-    if ($img = imce_image_info($path)) {
-      $width = $img['width'];
-      $height = $img['height'];
-    }
-    $size = filesize($path);
-    $date = filemtime($path);
-    $directory['files'][$file] = array(
-      'name' => $file,
-      'size' => $size,
-      'width' => $width,
-      'height' => $height,
-      'date' => $date
-    );
-    $directory['dirsize'] += $size;
-  }
-
-  closedir($handle);
-  sort($directory['subdirectories']);
-  return $directory;
-}
-
-/**
- * Create directory tree.
- */
-function imce_create_tree(&$imce) {
-  $paths = array();
-  //rearrange paths as arg0=>arg1=>...
-  foreach ($imce['directories'] as $path => $arr) {
-    $tmp =& $paths;
-    if ($path != '.') {
-      $args = explode('/', $path);
-      foreach ($args as $arg) {
-        if (!isset($tmp[$arg])) {
-          $tmp[$arg] = array();
-        }
-        $tmp =& $tmp[$arg];
-      }
-      $tmp[':access:'] = TRUE;
-    }
-    if ("$path" == $imce['dir']) {
-      $tmp[':active:'] = TRUE;
-      foreach ($imce['subdirectories'] as $arg) {
-        $tmp[$arg][':access:'] = TRUE;
-      }
-    }
-  }
-  //set root branch
-  $root = theme('imce_root_text', array('imce' => &$imce));
-  $q = $imce['clean'] ? '?' : '&';
-  if (isset($imce['directories']['.'])) {
-    $root = '<a href="'. $imce['url'] . $q .'dir=." title="." class="folder'. ($imce['dir'] == '.' ? ' active' : '') .'">'. $root .'</a>';
-  }
-  else {
-    $root = '<a title="." class="folder disabled">'. $root .'</a>';
-  }
-
-  return $root . imce_tree_html($imce, $paths, $q);
-}
-
-/**
- * Return tree html.
- * This is not themable because it is complex and needs to be in a proper format for js processing.
- */
-function imce_tree_html(&$imce, $paths, $q = '?', $prefix = '', $eprefix = '') {
-  unset($paths[':access:'], $paths[':active:']);
-  $html = '';
-  foreach ($paths as $arg => $children) {
-    $path = $prefix . $arg;
-    $earg = rawurlencode($arg);
-    $epath = $eprefix . $earg;
-    if (isset($children[':access:']) || imce_directory_info($path, $imce)) {
-      $a = '<a href="'. $imce['url'] . $q .'dir='. $epath .'" title="'. $epath .'" class="folder'. (isset($children[':active:']) ? ' active' : '') .'">'. $earg .'</a>';
-    }
-    else {
-      $a = '<a title="'. $epath .'" class="folder disabled">'. $earg .'</a>';
-    }
-    $ul = imce_tree_html($imce, $children, $q, $path .'/', $epath .'/');
-    $class = $ul ? ' class="expanded"' : (isset($children[':active:']) ? ' class="leaf"' : '');
-    $html .= '<li'. $class .'>'. $a . $ul .'</li>';
-  }
-  if ($html) {
-    $html = '<ul>'. $html .'</ul>';
-  }
-  return $html;
-}
-
-/**
- * Returns the text for the root directory in a directory tree.
- */
-function theme_imce_root_text($imce_ref) {
-  //$imce = &$imce_ref['imce'];
-  return '&lt;' . t('root') . '&gt;';
-}
-
-/**
- * Returns the html for user's file browser tab.
- */
-function theme_imce_user_page($account) {
-  global $user;
-  $options = array();
-  //switch to account's active folder
-  if ($user->uid == 1 && $account->uid != 1) {
-    $imce = imce_initiate_profile($account);
-    $options['query'] = array('dir' => $imce['dir']);
-  }
-  return '<iframe src="' . url('imce', $options) . '" frameborder="0" style="border: 1px solid #eee; width: 99%; height: 520px" class="imce-frame"></iframe>';
-}
-
-/**
- * Registers the file as an IMCE file.
- */
-function imce_file_register($file) {
-  return $file->fid && @db_query('INSERT INTO {imce_files} (fid) VALUES(%d)', $file->fid);
-}
+<?php
+// $Id: imce.page.inc,v 1.1 2010/08/31 16:36:44 c0aslm1 Exp $
+
+/**
+ * @file
+ * Implements the file browser.
+ */
+
+/**
+ * q = imce.
+ */
+function imce() {
+  module_invoke('admin_menu', 'suppress');//suppress admin_menu
+  $jsop = isset($_GET['jsop']) ? $_GET['jsop'] : NULL;
+  print imce_page($GLOBALS['user'], $jsop);
+  exit();
+}
+
+/**
+ * q = user/x/imce.
+ */
+function imce_user_page($account) {
+  return theme('imce_user_page', $account);
+}
+
+/**
+ * Returns the imce page for the specified user.
+ */
+function imce_page($user, $jsop = NULL) {
+  return theme('imce_page', imce_content($user, $jsop));
+}
+
+/**
+ * Returns the content of the file browser.
+ */
+function imce_content($user, $jsop = NULL) {
+
+  //execute ajax calls.
+  if ($jsop) {
+    return imce_js($user, $jsop);
+  }
+
+  //initiate configuration profile
+  if (!$imce = imce_initiate_profile($user)) {
+    return '';
+  }
+  imce_process_profile($imce);//get active directory content
+
+  //Before creating the content let's add main files required for imce to function properly.
+  $path = drupal_get_path('module', 'imce');
+  drupal_add_js($path . '/js/jquery.form.js');
+  drupal_add_js($path . '/js/imce.js');
+  drupal_add_js($path . '/js/imce_extras.js');
+  drupal_add_js("imce.upload_method = " . drupal_to_js(variable_get('imce_settings_replace', FILE_EXISTS_RENAME)) . ";", 'inline');
+  drupal_add_css($path . '/css/imce-content.css');
+
+  //process forms.
+  //reference imce inside an array so it will stay referenced during argument copy of drupal_get_form
+  $imce_ref = array('imce' => &$imce);
+  $forms = '';
+
+  if (!$imce['error']) {
+    //process file upload.
+    if (imce_perm_exists($imce, 'upload')) {
+      $forms .= drupal_get_form('imce_upload_form', $imce_ref);
+    }
+    //process file operations.
+    $forms .= drupal_get_form('imce_fileop_form', $imce_ref);
+  }
+
+  //run custom content functions. possible to insert extra forms. content is invisible when js is enabled.
+  foreach (variable_get('imce_custom_content', array()) as $func => $state) {
+    if ($state && function_exists($func) && $output = $func($imce)) {
+      $forms .= $output;
+    }
+  }
+
+  $content = theme('imce_content', imce_create_tree($imce), $forms, $imce_ref);
+
+  //make necessary changes for js conversion
+  $imce['dir'] = str_replace('%2F', '/', rawurlencode($imce['dir']));
+  unset($imce['files'], $imce['name'], $imce['directories'], $imce['subdirectories'], $imce['filesize'], $imce['quota'], $imce['tuquota'], $imce['thumbnails'], $imce['uid'], $imce['usertab']);
+
+  drupal_add_js($imce_ref, 'setting');
+
+  return $content;
+}
+
+/**
+ * Ajax operations. q=imce&jsop={op}
+ */
+function imce_js($user, $jsop = '') {
+  $response = array();
+
+  //data
+  if ($imce = imce_initiate_profile($user)) {
+    imce_process_profile($imce);
+    if (!$imce['error']) {
+      module_load_include('inc', 'imce', 'inc/imce.js');
+      if (function_exists($func = 'imce_js_'. $jsop)) {
+        $response['data'] = $func($imce);
+      }
+    }
+  }
+  //messages
+  $response['messages'] = drupal_get_messages();
+
+  //disable devel log.
+  $GLOBALS['devel_shutdown'] = FALSE;
+  //for upload we must return plain text header.
+  drupal_set_header('Content-Type: text/'. ($jsop == 'upload' ? 'html' : 'javascript') .'; charset=utf-8');
+  print drupal_to_js($response);
+  exit();
+}
+
+/**
+ * Upload form.
+ */
+function imce_upload_form(&$form_state, $ref) {
+  $imce =& $ref['imce'];
+  $form['imce'] = array(
+    '#type' => 'file',
+    '#title' => t('File'),
+    '#size' => 30,
+  );
+  if (!empty($imce['thumbnails'])) {
+    $form['thumbnails'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Create thumbnails'),
+      '#options' => imce_thumbnail_options($imce['thumbnails']),
+    );
+  }
+  $form['upload'] = array(
+    '#type' => 'submit',
+    '#value' => t('Upload'),
+    '#submit' => $imce['perm']['upload'] ? array('imce_upload_submit') : NULL,
+  );
+  $form = array('fset_upload' => array('#type' => 'fieldset', '#title' => t('Upload file')) + $form);
+  $form['#attributes']['enctype'] = 'multipart/form-data';
+  $form['#action'] = $imce['url'];
+  return $form;
+}
+
+/**
+ * File operations form.
+ */
+function imce_fileop_form(&$form_state, $ref) {
+  $imce =& $ref['imce'];
+  $form['filenames'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Selected files'),
+    '#maxlength' => $imce['filenum'] ? $imce['filenum']*255 : NULL,
+  );
+
+  //thumbnail
+  if (!empty($imce['thumbnails']) && imce_perm_exists($imce, 'thumb')) {
+    $form['fset_thumb'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Thumbnails'),
+    ) + imce_thumb_form($imce);
+  }
+
+  //delete
+  if (imce_perm_exists($imce, 'delete')) {
+    $form['fset_delete'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Delete'),
+    ) + imce_delete_form($imce);
+  }
+
+  //resize
+  if (imce_perm_exists($imce, 'resize')) {
+    $form['fset_resize'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Resize'),
+    ) + imce_resize_form($imce);
+  }
+ 
+  $form['#action'] = $imce['url'];
+  return $form;
+}
+
+/**
+ * Thumbnail form.
+ */
+function imce_thumb_form(&$imce) {
+  $form['thumbnails'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Thumbnails'),
+    '#options' => imce_thumbnail_options($imce['thumbnails']),
+  );
+  $form['thumb'] = array(
+    '#type' => 'submit',
+    '#value' => t('Create thumbnails'),
+    '#submit' => $imce['perm']['thumb'] ? array('imce_thumb_submit') : NULL,
+  );
+  return $form;
+}
+
+/**
+ * Delete form.
+ */
+function imce_delete_form(&$imce) {
+  $form['delete'] = array(
+    '#type' => 'submit',
+    '#value' => t('Delete'),
+    '#submit' => $imce['perm']['delete'] ? array('imce_delete_submit') : NULL,
+  );
+  return $form;
+}
+
+/**
+ * Resizing form.
+ */
+function imce_resize_form(&$imce) {
+  $form['width'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Width x Height'),
+    '#size' => 5,
+    '#maxlength' => 4,
+    '#prefix' => '<div class="container-inline">',
+  );
+  $form['height'] = array(
+    '#type' => 'textfield',
+    '#size' => 5,
+    '#maxlength' => 4,
+    '#prefix' => 'x',
+  );
+  $form['resize'] = array(
+    '#type' => 'submit',
+    '#value' => t('Resize'),
+    '#submit' => $imce['perm']['resize'] ? array('imce_resize_submit') : NULL,//permission for submission
+    '#suffix' => '</div>',
+  );
+  $form['copy'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Create a new image'),
+    '#default_value' => 1,
+  );
+  return $form;
+}
+
+/**
+ * Validate file operations form.
+ */
+function imce_fileop_form_validate($form, &$form_state) {
+  $imce =& $form['#parameters'][2]['imce'];
+
+  //check if the filenames is empty
+  if ($form_state['values']['filenames'] == '') {
+    return form_error($form['filenames'], t('Please select a file.'));
+  }
+
+  //filenames come seperated by colon
+  $filenames = explode(':', $form_state['values']['filenames']);
+  $cnt = count($filenames);
+  //check the number of files.
+  if ($imce['filenum'] && $cnt > $imce['filenum']) {
+    return form_error($form['filenames'], t('You are not allowed to operate on more than %num files.', array('%num' => $imce['filenum'])));
+  }
+
+  //check if there is any illegal choice
+  for ($i = 0; $i < $cnt; $i++) {
+    $filenames[$i] = $filename = rawurldecode($filenames[$i]);
+    if (!isset($imce['files'][$filename])) {
+      watchdog('imce', 'Illegal choice %choice in !name element.', array('%choice' => $filename, '!name' => t('directory (%dir)', array('%dir' => file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir'])))), WATCHDOG_ERROR);
+      return form_error($form['filenames'], t('An illegal choice has been detected. Please contact the site administrator.'));
+    }
+  }
+
+  $form_state['values']['filenames'] = $filenames;
+}
+
+/**
+ * Submit upload form.
+ */
+function imce_upload_submit($form, &$form_state) {
+  $form_state['redirect'] = FALSE;
+  $imce =& $form['#parameters'][2]['imce'];
+  $validators = array('imce_validate_all' => array(&$imce));
+  $dirpath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']);
+
+  //save uploaded file.
+  $replace = variable_get('imce_settings_replace', FILE_EXISTS_RENAME);
+  if ($file = file_save_upload('imce', $validators, $dirpath, $replace)) {
+
+    //core bug #203204.
+    @chmod($file->filepath, 0664);
+
+    //core bug #54223.
+    if ($replace == FILE_EXISTS_RENAME) {
+      $name = basename($file->filepath);
+      if ($name != $file->filename) {
+        $file->filename = $name;
+        drupal_set_message(t('The file has been renamed to %filename.', array('%filename' => $file->filename)));
+      }
+    }
+    elseif ($replace == FILE_EXISTS_REPLACE) {//check duplicates
+      if ($_file = db_fetch_object(db_query("SELECT fid FROM {files} WHERE filepath = '%s' AND fid <> %d", $file->filepath, $file->fid))) {
+        db_query("DELETE FROM {files} WHERE fid = %d", $file->fid);
+        $file->fid = $_file->fid;
+      }
+    }
+
+    $file->uid = $imce['uid'];//global user may not be the owner.
+    $file->status = FILE_STATUS_PERMANENT;//make permanent
+    drupal_write_record('files', $file, array('fid'));//update
+    imce_file_register($file);
+    drupal_set_message(t('%filename has been uploaded.', array('%filename' => $file->filename)));
+
+    //update file list
+    $img = imce_image_info($file->filepath);
+    $file->width = $img ? $img['width'] : 0;
+    $file->height = $img ? $img['height'] : 0;
+    imce_add_file($file, $imce);
+
+    //create thumbnails
+    if (isset($form_state['values']['thumbnails']) && $img) {
+      imce_create_thumbnails($file->filename, $imce, $form_state['values']['thumbnails']);
+    }
+  }
+  else {
+    drupal_set_message(t('Upload failed.'), 'error');
+  }
+}
+
+/**
+ * Submit thumbnail form.
+ */
+function imce_thumb_submit($form, &$form_state) {
+  $form_state['redirect'] = FALSE;
+  $imce =& $form['#parameters'][2]['imce'];
+  //create thumbnails
+  imce_process_files($form_state['values']['filenames'], $imce, 'imce_create_thumbnails', array($form_state['values']['thumbnails']));
+}
+
+/**
+ * Submit delete form.
+ */
+function imce_delete_submit($form, &$form_state) {
+  $form_state['redirect'] = FALSE;
+  $imce =& $form['#parameters'][2]['imce'];
+
+  $deleted = imce_process_files($form_state['values']['filenames'], $imce, 'imce_delete_file');
+
+  if (!empty($deleted)) {
+    drupal_set_message(t('File deletion successful: %files.', array('%files' => utf8_encode(implode(', ', $deleted)))));
+  }
+
+}
+
+/**
+ * Submit resize form.
+ */
+function imce_resize_submit($form, &$form_state) {
+  $form_state['redirect'] = FALSE;
+  $imce =& $form['#parameters'][2]['imce'];
+
+  //check dimensions
+  $width = (int) $form_state['values']['width'];
+  $height = (int) $form_state['values']['height'];
+  list($maxw, $maxh) = explode('x', $imce['dimensions']);
+  if ($width < 1 || $height < 1 || ($maxw && ($width > $maxw || $height > $maxh))) {
+    drupal_set_message(t('Please specify dimensions within the allowed range that is from 1x1 to @dimensions.', array('@dimensions' => $imce['dimensions'] ? $imce['dimensions'] : t('unlimited'))), 'error');
+    return;
+  }
+
+  $resized = imce_process_files($form_state['values']['filenames'], $imce, 'imce_resize_image', array($width, $height, $form_state['values']['copy']));
+
+  if (!empty($resized)) {
+    drupal_set_message(t('File resizing successful: %files.', array('%files' => utf8_encode(implode(', ', $resized)))));
+  }
+
+}
+
+/**
+ * Do batch operations on files.
+ * Used by delete, resize, create thumbnail submissions.
+ */
+function imce_process_files($filenames, &$imce, $function, $args = array()) {
+  $args = array_merge(array('', &$imce), $args);
+  $processed = array();
+
+  foreach ($filenames as $filename) {
+    $args[0] = $filename;
+    if (call_user_func_array($function, $args)) {
+      $processed[] = $filename;
+    }
+  }
+
+  return $processed;
+}
+
+/**
+ * Delete a file in the file list.
+ */
+function imce_delete_file($filename, &$imce) {
+  $filepath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']) .'/'. $filename;
+  if (!imce_delete_filepath($filepath)) {
+    return FALSE;
+  }
+  imce_remove_file($filename, $imce);
+  return TRUE;
+}
+
+/**
+ * Delete a file by path.
+ */
+function imce_delete_filepath($filepath) {
+  $file = db_fetch_object(db_query("SELECT * FROM {files} WHERE filepath = '%s'", $filepath));
+
+  //file exists in database
+  if ($file) {
+    //prevent imce returning ref count
+    $file->imce_noref = TRUE;
+    //check references
+    $refs = array_filter(module_invoke_all('file_references', $file));
+    //file is in use
+    if (!empty($refs)) {
+      drupal_set_message(t('%filename is in use by another application.', array('%filename' => $file->filename)), 'error');
+      return FALSE;
+    }
+    //prepare deletion
+    module_invoke_all('file_delete', $file);
+    if (!file_delete($file->filepath)) {
+      return FALSE;
+    }
+    db_query('DELETE FROM {files} WHERE fid = %d', $file->fid);
+  }
+  //not in db. probably loaded via ftp.
+  elseif (!file_delete($filepath)) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+ * Create all selected thumbnails.
+ */
+function imce_create_thumbnails($filename, &$imce, $values) {
+  $created = array();
+  foreach ($imce['thumbnails'] as $thumbnail) {
+    if ($values[$thumbnail['name']] && imce_create_thumbnail($filename, $imce, $thumbnail)) {
+      $created[] = $thumbnail['name'];
+    }
+  }
+  if (!empty($created)) {
+  drupal_set_message(t('Thumbnail creation (%thumbnames) successful for %filename.', array('%thumbnames' => implode(', ', $created), '%filename' => utf8_encode($filename))));
+  }
+  return $created;
+}
+
+/**
+ * Create a thumbnail.
+ */
+function imce_create_thumbnail($filename, &$imce, $thumbnail) {
+  //generate thumbnail name
+  $name = $thumbnail['prefix'];
+  if ($thumbnail['suffix'] != '' && $dot = strrpos($filename, '.')) {
+    $name .= substr($filename, 0, $dot);
+    $name .= $thumbnail['suffix'];
+    $name .= substr($filename, $dot);
+  }
+  else {
+    $name .= $filename;
+  }
+  //scale the image
+  list($width, $height) = explode('x', $thumbnail['dimensions']);
+  return imce_resize_image($filename, $imce, $width, $height, TRUE, $name, variable_get('imce_settings_thumb_method', 'scale_and_crop'));
+}
+
+/**
+ * Resize an image in the file list. Also used for thumbnail creation.
+ */
+function imce_resize_image($filename, &$imce, $width, $height, $copy = TRUE, $dest = FALSE, $op = 'resize') {
+  $dirpath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']);
+  $filepath = $dirpath .'/'. $filename;
+
+  //check if the file is an image
+  if (!$imce['files'][$filename]['width'] || !$img = imce_image_info($filepath)) {
+    drupal_set_message(t('%filename is not an image.', array('%filename' => utf8_encode($filename))), 'error', FALSE);
+    return FALSE;
+  }
+
+  if (substr($op, 0, 5) == 'scale' && !($width < $img['width'] || $height < $img['height'])) {
+    drupal_set_message(t('Scaling up is not allowed.'), 'error', FALSE);
+    return FALSE;
+  }
+
+  //create file object
+  $file = new stdClass();
+  $file->filepath = $dirpath .'/'. $dest;
+  if (!$dest || $dest == $filename) {
+    $file->filepath = $copy ? file_create_filename($filename, $dirpath) : $filepath;
+  }
+  $file->filename = basename($file->filepath);
+
+  //check if a file having the same properties exists already.
+  if (isset($imce['files'][$file->filename])) {
+    if (($f = $imce['files'][$file->filename]) && $f['width'] == $width && $f['height'] == $height) {
+      drupal_set_message(t('%filename(%dimensions) already exists.', array('%filename' => utf8_encode($file->filename), '%dimensions' => $width .'x'. $height)), 'error');
+      return FALSE;
+    }
+  }
+
+  //validate file name
+  $errors = file_validate_name_length($file);
+  if (!empty($errors)) {
+    drupal_set_message($errors[0], 'error');
+    return FALSE;
+  }
+
+  //resize image to a temp file
+  $temp = tempnam(realpath(file_directory_temp()), 'imc');
+  register_shutdown_function('file_delete', $temp);
+  $function = 'image_'. $op;
+  if (!$function($filepath, $temp, $width, $height)) {
+    drupal_set_message(t('%filename cannot be resized to %dimensions', array('%filename' => utf8_encode($filename), '%dimensions' => $width .'x'. $height)), 'error', FALSE);
+    return FALSE;
+  }
+
+  //validate quota
+  $file->filesize = filesize($temp);
+  $overwrite = $file->filename == $filename;
+  if (!imce_validate_quotas($file, $imce, $overwrite ? -$imce['files'][$filename]['size'] : 0)) {
+    return FALSE;
+  }
+
+  //copy from temp to filepath
+  if (!@copy($temp, $file->filepath)) {
+    drupal_set_message(t('The selected file %file could not be copied.', array('%file' => utf8_encode($file->filename))), 'error', FALSE);
+    return FALSE;
+  }
+  @chmod($file->filepath, 0664);
+
+  //build the rest of the file object
+  $file->uid = $imce['uid'];
+  $file->filemime = $img['mime'];
+  $file->status = FILE_STATUS_PERMANENT;
+  $file->timestamp = time();
+
+  //if we are overwriting the file and it is already in database.
+  $update = array();
+  if ($overwrite && $_file = db_fetch_object(db_query("SELECT f.* FROM {files} f WHERE f.filepath = '%s'", $file->filepath))) {
+    $file->fid = $_file->fid;
+    $file->uid = $_file->uid;
+    $update[] = 'fid';
+  }
+
+  //save the file
+  drupal_write_record('files', $file, $update);
+  imce_file_register($file);
+
+  //update file list
+  //if the file was scaled get the new dimensions
+  if ($op == 'scale') {
+    $img = imce_image_info($file->filepath);
+    $width = $img['width'];
+    $height = $img['height'];
+  }
+  $file->width = $width;
+  $file->height = $height;
+  imce_add_file($file, $imce);
+
+  return $file;
+}
+
+/**
+ * Add a new file to the file list.
+ */
+function imce_add_file($file, &$imce) {
+  $imce['dirsize'] += $file->filesize;
+  if (isset($imce['files'][$file->filename])) {
+    $imce['dirsize'] -= $imce['files'][$file->filename]['size'];
+  }
+  $imce['files'][$file->filename] = array(
+    'name' => $file->filename,
+    'size' => $file->filesize,
+    'width' => $file->width,
+    'height' => $file->height,
+    'date' => $file->timestamp
+  );
+  if (isset($_GET['jsop'])) {
+    $add = $imce['files'][$file->filename];
+    $add['name'] = rawurlencode($file->filename);
+    $add['fsize'] = format_size($file->filesize);
+    $add['fdate'] = format_date($file->timestamp, 'small');
+    $add['id'] = $file->fid;
+    $imce['added'][] = $add;
+  }
+}
+
+/**
+ * Remove a file from the file list.
+ */
+function imce_remove_file($filename, &$imce) {
+  if (isset($imce['files'][$filename])) {
+    $imce['dirsize'] -= $imce['files'][$filename]['size'];
+    unset($imce['files'][$filename]);
+    if (isset($_GET['jsop'])) {
+      $imce['removed'][] = rawurlencode($filename);
+    }
+  }
+}
+
+/**
+ * Validate uploaded file.
+ */
+function imce_validate_all(&$file, $imce) {
+
+  //fix FILE_EXISTS_ERROR bug. core bug #54223.
+  if (!$file->destination && variable_get('imce_settings_replace', FILE_EXISTS_RENAME) == FILE_EXISTS_ERROR) {
+    return array(t('File browser is set to reject the upload of existing files.'));
+  }
+
+  //validate image resolution only if filesize validation passes.
+  //because user might have uploaded a very big image
+  //and scaling it may exploit system memory.
+  $errors = imce_validate_filesize($file, $imce['filesize']);
+  //image resolution validation
+  if (empty($errors)) {
+    $errors = array_merge($errors, file_validate_image_resolution($file, $imce['dimensions']));
+  }
+  //directory quota validation
+  if ($imce['quota']) {
+    $errors = array_merge($errors, imce_validate_quota($file, $imce['quota'], $imce['dirsize']));
+  }
+  //file extension validation
+  if ($imce['extensions'] != '*') {
+    $errors = array_merge($errors, file_validate_extensions($file, $imce['extensions']));
+  }
+  //user quota validation. check it if no errors were thrown.
+  if (empty($errors) && $imce['tuquota']) {
+    $errors = imce_validate_tuquota($file, $imce['tuquota'], file_space_used($imce['uid']));
+  }
+  return $errors;
+}
+
+/**
+ * Validate filesize for maximum allowed file size.
+ */
+function imce_validate_filesize($file, $maxsize = 0) {
+  $errors = array();
+  if ($maxsize && $file->filesize > $maxsize) {
+    $errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($file->filesize), '%maxsize' => format_size($maxsize)));
+  }
+  return $errors;
+}
+
+/**
+ * Validate filesize for directory quota.
+ */
+function imce_validate_quota($file, $quota = 0, $currentsize = 0) {
+  $errors = array();
+  if ($quota && ($currentsize + $file->filesize) > $quota) {
+    $errors[] = t('%filename is %filesize which would exceed your directory quota. You are currently using %size of %total_quota.', array('%size' => format_size($currentsize), '%total_quota' => format_size($quota), '%filesize' => format_size($file->filesize), '%filename' => utf8_encode($file->filename)));
+  }
+  return $errors;
+}
+
+/**
+ * Validate filesize for total user quota.
+ */
+function imce_validate_tuquota($file, $quota = 0, $currentsize = 0) {
+  $errors = array();
+  if ($quota && ($currentsize + $file->filesize) > $quota) {
+    $errors[] = t('%filename is %filesize which would exceed your total user quota. You are currently using %size of %total_quota.', array('%size' => format_size($currentsize), '%total_quota' => format_size($quota), '%filesize' => format_size($file->filesize), '%filename' => utf8_encode($file->filename)));
+  }
+  return $errors;
+}
+
+/**
+ * Validate both directory and total user quota. Returns true/false not errors.
+ */
+function imce_validate_quotas($file, &$imce, $add = 0) {
+  $errors = imce_validate_quota($file, $imce['quota'], $imce['dirsize'] + $add);
+  if (empty($errors) && $imce['tuquota']) {
+    $errors = imce_validate_tuquota($file, $imce['tuquota'], file_space_used($imce['uid']) + $add);
+  }
+  if (!empty($errors)) {
+    drupal_set_message($errors[0], 'error');
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+ * Check if the file is an image and return info.
+ */
+function imce_image_info($file) {
+  if (is_file($file) && ($dot = strrpos($file, '.')) && in_array(strtolower(substr($file, $dot+1)), array('jpg', 'jpeg', 'gif', 'png')) && ($info = @getimagesize($file)) && in_array($info[2], array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG)) ) {
+    return array('width' => $info[0], 'height' => $info[1], 'type' => $info[2], 'mime' => $info['mime']);
+  }
+  return FALSE;
+}
+
+/**
+ * Return thumbnails as options to be used in upload form.
+ */
+function imce_thumbnail_options($thumbs = array()) {
+  $options = array();
+  foreach ($thumbs as $thumb) {
+    $options[$thumb['name']] = $thumb['name'] .' ('. $thumb['dimensions'] .')';
+  }
+  return $options;
+}
+
+/**
+ * Initiate and return configuration profile for the $user.
+ */
+function imce_initiate_profile($user) {
+
+  //check user profile and translate tokens in directory paths and evaluate php paths.
+  if ($imce = imce_user_profile($user)) {
+    imce_process_directories($imce, $user);
+    if (!empty($imce['directories'])) {
+      $imce['uid'] = (int) $user->uid;
+      $imce['url'] = url($_GET['q']);
+      $imce['clean'] = variable_get('clean_url', 0) == 1;
+      $imce['absurls'] = variable_get('imce_settings_absurls', 0) == 1;
+      $imce['furl'] = file_create_url('');
+      $imce['filesize'] *= 1048576;//convert from Mb to byte
+      $imce['quota'] *= 1048576;
+      $imce['tuquota'] *= 1048576;
+      $imce['filenum'] = (int) $imce['filenum'];
+      //check and set the active directory
+      if ($info = imce_working_directory($imce)) {
+        $imce['direct'] = isset($imce['directories'][$info['name']]);
+        $imce['directories'][$info['name']] = $info;
+        $imce['dir'] = $info['name'];
+        $imce['perm'] = $info;//copy permissions of the active directory.
+        unset($imce['perm']['name']);
+      }
+      else {
+        drupal_set_message(t('Unable to get a working directory for the file browser!'), 'error');
+        $imce['dir'] = FALSE;
+        $imce['error'] = TRUE;
+      }
+      return $imce;
+    }
+    drupal_set_message(t('There is no valid directory specified for the file browser!'), 'error');
+  }
+  else {
+    drupal_set_message(t('You do not have access to any configuration profile to use the file browser!'), 'error');
+  }
+
+  return FALSE;
+}
+
+/**
+ * Get files and folders of the actve directory. Do custom processing.
+ */
+function imce_process_profile(&$imce) {
+  //get directory content. do a custom scan if it is set
+  $scan = ($scan = variable_get('imce_custom_scan', '')) && function_exists($scan) ? $scan : 'imce_scan_directory';
+  $imce += $scan($imce['dir'], $imce);
+
+  //run custom process functions
+  foreach (variable_get('imce_custom_process', array()) as $func => $state) {
+    if ($state && function_exists($func)) {
+      $func($imce);
+    }
+  }
+
+  //set subdirectories
+  if (!$imce['error'] && !imce_subdirectories_accessible($imce)) {
+    $imce['subdirectories'] = array();
+  }
+}
+
+/**
+ * Translate tokens and evaluate php in directory names.
+ * Convert directories into an associative array (dirname => info)
+ */
+function imce_process_directories(&$imce, $user) {
+  $directories = $imce['directories'];
+  $paths = array();
+  $translate = array('%uid' => $user->uid);
+
+  foreach ($directories as $directory) {
+    if (substr($directory['name'], 0, 4) == 'php:') {
+      $directory['name'] = eval(substr($directory['name'], 4));
+     //php may return an array of directories
+      if (is_array($directory['name'])) {
+        foreach ($directory['name'] as $name) {
+          $paths[$name] = array('name' => $name) + $directory;
+        }
+        continue;
+      }
+    }
+    else {
+      $directory['name'] = strtr($directory['name'], $translate);
+    }
+    if ($directory['name']) {
+      $paths[$directory['name']] = $directory;
+    }
+  }
+
+  $imce['directories'] = $paths;
+}
+
+/**
+ * Return an avaliable directory for the profile.
+ */
+function imce_working_directory(&$imce) {
+  //Do not use session if there is only one directory assigned.
+  $sess = TRUE;
+  if (count($imce['directories']) < 2) {
+    $perms = reset($imce['directories']);
+    if (!isset($perms['subnav']) || !$perms['subnav']) {
+      $sess = FALSE;
+    }
+  }
+  //check GET.
+  if (isset($_GET['dir'])) {
+    if ($info = imce_directory_info($_GET['dir'], $imce)) {
+      if (imce_check_directory($_GET['dir'], $imce)) {
+        if ($sess) {
+          $_SESSION['imce_directory'] = rawurlencode($info['name']);
+        }
+      }
+      else {
+        $info = FALSE;
+      }
+    }
+    else {
+      imce_inaccessible_directory($_GET['dir'], $imce);
+    }
+    return $info;
+  }
+
+  //check session
+  if ($sess && isset($_SESSION['imce_directory'])) {
+    $dirname = rawurldecode($_SESSION['imce_directory']);
+    if ($info = imce_directory_info($dirname, $imce)) {
+      if (imce_check_directory($dirname, $imce)) {
+        return $info;
+      }
+    }
+  }
+
+  //or the whole list.
+  foreach ($imce['directories'] as $dirname => $info) {
+    if (imce_check_directory($dirname, $imce)) {
+      if ($sess) {
+        $_SESSION['imce_directory'] = rawurlencode($dirname);
+      }
+      return $info;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+ * Create a writable directory(any level) under file system directory.
+ */
+function imce_check_directory($dirname, $imce = array()) {
+
+  $root = file_directory_path();
+  $dirpath = $root .'/'. $dirname;
+
+  if (!file_check_directory($dirpath)) {//directory does not exist. try to create it.
+    $path = $root;
+    foreach (explode('/', $dirname) as $arg) {
+      $path .= '/'. $arg;
+      if (!file_check_location($path, $root) || !file_check_directory($path, FILE_CREATE_DIRECTORY)) {
+        return imce_inaccessible_directory($dirname, $imce);
+      }
+    }
+  }
+  elseif (!file_check_location($dirpath, $root)) {//directory exists outside of root.
+    return imce_inaccessible_directory($dirname, $imce);
+  }
+
+  return TRUE;
+}
+
+/**
+ * Generate and log a directory access error.
+ */
+function imce_inaccessible_directory($dirname, $imce = array()) {
+  if (is_string($dirname)) {
+    $dirname = utf8_encode($dirname);
+    drupal_set_message(t('Directory %dirname is not accessible.', array('%dirname' => $dirname)), 'error');
+    watchdog('imce', 'Access to %directory was denied.', array('%directory' => $dirname), WATCHDOG_ERROR);
+  }
+  return FALSE;
+}
+
+/**
+ * Return the permissions for a directory that is accessed directly or indirectly.
+ * A child of a predefined directory in the directory list takes its parent's properties.
+ * If it has multiple parents, it gets the properties of the latter in the list.
+ */
+function imce_directory_info($dirname, $imce) {
+
+  if (isset($imce['directories'][$dirname])) {
+    return $imce['directories'][$dirname];
+  }
+
+  $info = FALSE;
+  $root = file_directory_path();
+  $dirpath = $root .'/'. $dirname;
+  if (imce_reg_dir($dirname) && file_check_directory($dirpath)) {
+    foreach ($imce['directories'] as $name => $prop) {
+      if ($prop['subnav'] && file_check_location($dirpath, $root .'/'. $name)) {
+        $info = $prop;
+        $info['name'] = $dirname;
+      }
+    }
+  }
+
+  return $info;
+}
+
+/**
+ * Detect if the subdirectories are accessible through any directory(not just the current one) in the list.
+ */
+function imce_subdirectories_accessible(&$imce) {
+
+  if (!empty($imce['subdirectories'])) {
+    $root = file_directory_path() .'/';
+    //checking only the first one is sufficient.
+    $dirname = ($imce['dir'] == '.' ? '' : $imce['dir'] .'/') . $imce['subdirectories'][0];
+    $dirpath = $root . $dirname;
+
+    //check if any setting is applicable for this subdirectory through any directory in the list.
+    foreach ($imce['directories'] as $name => $info) {
+      if ($info['subnav'] && $dirname != $name && file_check_location($dirpath, $root . $name)) {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+ * Check if a permission is given to at least one directory in the list.
+ */
+function imce_perm_exists(&$imce, $perm) {
+  static $perms = array();
+
+  if (isset($perms[$perm])) {
+    return $perms[$perm];
+  }
+
+  if (isset($imce['perm'][$perm]) && $imce['perm'][$perm]) {
+    return $perms[$perm] = TRUE;
+  }
+
+  foreach ($imce['directories'] as $name => $info) {
+    if (isset($info[$perm]) && $info[$perm]) {
+      return $perms[$perm] = TRUE;
+    }
+  }
+
+  return $perms[$perm] = FALSE;
+}
+
+/**
+ * Scan directory and return file list, subdirectories, and total size.
+ */
+function imce_scan_directory($dirname, $imce = array()) {
+
+  $directory = array('dirsize' => 0, 'files' => array(), 'subdirectories' => array(), 'error' => FALSE);
+  $dirpath = file_directory_path() .'/'. $dirname;
+
+  if (!is_string($dirname) || $dirname == '' || !$handle = opendir($dirpath)) {
+    imce_inaccessible_directory($dirname, $imce);
+    $directory['error'] = TRUE;
+    return $directory;
+  }
+
+  $exclude = array('.' => 1, '..' => 1, 'CVS' => 1, '.svn' => 1, '.htaccess' => 1);
+  while (($file = readdir($handle)) !== FALSE) {
+    if (isset($exclude[$file])) {
+      continue;
+    }
+
+    $path = $dirpath .'/'. $file;
+
+    if (is_dir($path)) {
+      $directory['subdirectories'][] = $file;
+      continue;
+    }
+
+    $width = $height = 0;
+    if ($img = imce_image_info($path)) {
+      $width = $img['width'];
+      $height = $img['height'];
+    }
+    $size = filesize($path);
+    $date = filemtime($path);
+    $directory['files'][$file] = array(
+      'name' => $file,
+      'size' => $size,
+      'width' => $width,
+      'height' => $height,
+      'date' => $date
+    );
+    $directory['dirsize'] += $size;
+  }
+
+  closedir($handle);
+  sort($directory['subdirectories']);
+  return $directory;
+}
+
+/**
+ * Create directory tree.
+ */
+function imce_create_tree(&$imce) {
+  $paths = array();
+  //rearrange paths as arg0=>arg1=>...
+  foreach ($imce['directories'] as $path => $arr) {
+    $tmp =& $paths;
+    if ($path != '.') {
+      $args = explode('/', $path);
+      foreach ($args as $arg) {
+        if (!isset($tmp[$arg])) {
+          $tmp[$arg] = array();
+        }
+        $tmp =& $tmp[$arg];
+      }
+      $tmp[':access:'] = TRUE;
+    }
+    if ("$path" == $imce['dir']) {
+      $tmp[':active:'] = TRUE;
+      foreach ($imce['subdirectories'] as $arg) {
+        $tmp[$arg][':access:'] = TRUE;
+      }
+    }
+  }
+  //set root branch
+  $root = theme('imce_root_text', array('imce' => &$imce));
+  $q = $imce['clean'] ? '?' : '&';
+  if (isset($imce['directories']['.'])) {
+    $root = '<a href="'. $imce['url'] . $q .'dir=." title="." class="folder'. ($imce['dir'] == '.' ? ' active' : '') .'">'. $root .'</a>';
+  }
+  else {
+    $root = '<a title="." class="folder disabled">'. $root .'</a>';
+  }
+
+  return $root . imce_tree_html($imce, $paths, $q);
+}
+
+/**
+ * Return tree html.
+ * This is not themable because it is complex and needs to be in a proper format for js processing.
+ */
+function imce_tree_html(&$imce, $paths, $q = '?', $prefix = '', $eprefix = '') {
+  unset($paths[':access:'], $paths[':active:']);
+  $html = '';
+  foreach ($paths as $arg => $children) {
+    $path = $prefix . $arg;
+    $earg = rawurlencode($arg);
+    $epath = $eprefix . $earg;
+    if (isset($children[':access:']) || imce_directory_info($path, $imce)) {
+      $a = '<a href="'. $imce['url'] . $q .'dir='. $epath .'" title="'. $epath .'" class="folder'. (isset($children[':active:']) ? ' active' : '') .'">'. $earg .'</a>';
+    }
+    else {
+      $a = '<a title="'. $epath .'" class="folder disabled">'. $earg .'</a>';
+    }
+    $ul = imce_tree_html($imce, $children, $q, $path .'/', $epath .'/');
+    $class = $ul ? ' class="expanded"' : (isset($children[':active:']) ? ' class="leaf"' : '');
+    $html .= '<li'. $class .'>'. $a . $ul .'</li>';
+  }
+  if ($html) {
+    $html = '<ul>'. $html .'</ul>';
+  }
+  return $html;
+}
+
+/**
+ * Returns the text for the root directory in a directory tree.
+ */
+function theme_imce_root_text($imce_ref) {
+  //$imce = &$imce_ref['imce'];
+  return '&lt;' . t('root') . '&gt;';
+}
+
+/**
+ * Returns the html for user's file browser tab.
+ */
+function theme_imce_user_page($account) {
+  global $user;
+  $options = array();
+  //switch to account's active folder
+  if ($user->uid == 1 && $account->uid != 1) {
+    $imce = imce_initiate_profile($account);
+    $options['query'] = array('dir' => $imce['dir']);
+  }
+  return '<iframe src="' . url('imce', $options) . '" frameborder="0" style="border: 1px solid #eee; width: 99%; height: 520px" class="imce-frame"></iframe>';
+}
+
+/**
+ * Registers the file as an IMCE file.
+ */
+function imce_file_register($file) {
+  return $file->fid && @db_query('INSERT INTO {imce_files} (fid) VALUES(%d)', $file->fid);
+}
--- js/imce.js	2010-11-01 09:23:27.000000000 -0400
+++ js/imce.js	2010-10-29 16:33:20.000000000 -0400
@@ -1,799 +1,830 @@
-// $Id: imce.js,v 1.2 2010/08/31 16:36:17 c0aslm1 Exp $
-
-(function($) {
-//Global container.
-window.imce = {tree: {}, findex: [], fids: {}, selected: {}, selcount: 0, ops: {}, cache: {}, urlId: {},
-vars: {previewImages: 1, cache: 1},
-hooks: {load: [], list: [], navigate: [], cache: []},
-
-//initiate imce.
-initiate: function() {
-  imce.conf = Drupal.settings.imce || {};
-  if (imce.conf.error != false) return;
-  imce.FLW = imce.el('file-list-wrapper');
-  imce.SBW = imce.el('sub-browse-wrapper');
-  imce.updateUI();
-  imce.prepareMsgs();//process initial status messages
-  imce.initiateTree();//build directory tree
-  imce.hooks.list.unshift(imce.processRow);//set the default list-hook.
-  imce.initiateList();//process file list
-  imce.initiateOps();//prepare operation tabs
-  imce.refreshOps();
-  imce.invoke('load', window);//run functions set by external applications.
-},
-
-/**************** DIRECTORIES ********************/
-
-//process navigation tree
-initiateTree: function() {
-  $('#navigation-tree li').each(function(i) {
-    var a = this.firstChild, txt = a.firstChild;
-    txt && (txt.data = imce.decode(txt.data));
-    var branch = imce.tree[a.title] = {'a': a, li: this, ul: this.lastChild.tagName == 'UL' ? this.lastChild : null};
-    if (a.href) imce.dirClickable(branch);
-    imce.dirCollapsible(branch);
-  });
-},
-
-//Add a dir to the tree under parent
-dirAdd: function(dir, parent, clickable) {
-  if (imce.tree[dir]) return clickable ? imce.dirClickable(imce.tree[dir]) : imce.tree[dir];
-  var parent = parent || imce.tree['.'];
-  parent.ul = parent.ul ? parent.ul : parent.li.appendChild(imce.newEl('ul'));
-  var branch = imce.dirCreate(dir, imce.decode(dir.substr(dir.lastIndexOf('/')+1)), clickable);
-  parent.ul.appendChild(branch.li);
-  return branch;
-},
-
-//create list item for navigation tree
-dirCreate: function(dir, text, clickable) {
-  if (imce.tree[dir]) return imce.tree[dir];
-  var branch = imce.tree[dir] = {li: imce.newEl('li'), a: imce.newEl('a')};
-  $(branch.a).addClass('folder').text(text).attr('title', dir).appendTo(branch.li);
-  imce.dirCollapsible(branch);
-  return clickable ? imce.dirClickable(branch) : branch;
-},
-
-//change currently active directory
-dirActivate: function(dir) {
-  if (dir != imce.conf.dir) {
-    if (imce.tree[imce.conf.dir]){
-      $(imce.tree[imce.conf.dir].a).removeClass('active');
-    }
-    $(imce.tree[dir].a).addClass('active');
-    imce.conf.dir = dir;
-  }
-  return imce.tree[imce.conf.dir];
-},
-
-//make a dir accessible
-dirClickable: function(branch) {
-  if (branch.clkbl) return branch;
-  $(branch.a).attr('href', '#').removeClass('disabled').click(function() {imce.navigate(this.title); return false;});
-  branch.clkbl = true;
-  return branch;
-},
-
-//sub-directories expand-collapse ability
-dirCollapsible: function (branch) {
-  if (branch.clpsbl) return branch;
-  $(imce.newEl('span')).addClass('expander').html('&nbsp;').click(function() {
-    if (branch.ul) {
-      $(branch.ul).toggle();
-      $(branch.li).toggleClass('expanded');
-    }
-    else if (branch.clkbl){
-      $(branch.a).click();
-    }
-  }).prependTo(branch.li);
-  branch.clpsbl = true;
-  return branch;
-},
-
-//update navigation tree after getting subdirectories.
-dirSubdirs: function(dir, subdirs) {
-  var branch = imce.tree[dir];
-  if (subdirs && subdirs.length) {
-    var prefix = dir == '.' ? '' : dir +'/';
-    for (var i in subdirs) {//add subdirectories
-      imce.dirAdd(prefix + subdirs[i], branch, true);
-    }
-    $(branch.li).removeClass('leaf').addClass('expanded');
-    $(branch.ul).show();
-  }
-  else if (!branch.ul){//no subdirs->leaf
-    $(branch.li).removeClass('expanded').addClass('leaf');
-  }
-},
-
-/**************** FILES ********************/
-
-//process file list
-initiateList: function(cached) {
-  var L = imce.hooks.list, dir = imce.conf.dir, token = {'%dir':  dir == '.' ? $(imce.tree['.'].a).text() : imce.decode(dir)}
-  imce.findex = [], imce.fids = {}, imce.selected = {}, imce.selcount = 0, imce.vars.lastfid = null;
-  imce.tbody = imce.el('file-list').tBodies[0];
-  if (imce.tbody.rows.length) {
-    for (var row, i = 0; row = imce.tbody.rows[i]; i++) {
-      var fid = row.id;
-      imce.findex[i] = imce.fids[fid] = row;
-      if (cached) {
-        if (imce.hasC(row, 'selected')) {
-          imce.selected[imce.vars.lastfid = fid] = row;
-          imce.selcount++;
-        }
-      }
-      else {
-        for (var func, j = 0; func = L[j]; j++) func(row);//invoke list-hook
-      }
-    }
-  }
-  if (!imce.conf.perm.browse) {
-    imce.setMessage(Drupal.t('File browsing is disabled in directory %dir.', token), 'error');
-  }
-},
-
-//add a file to the list. (having properties name,size,formatted size,width,height,date,formatted date)
-fileAdd: function(file) {
-  var row, fid = file.name, i = imce.findex.length, attr = ['name', 'size', 'width', 'height', 'date'];
-  if (!(row = imce.fids[fid])) {
-    row = imce.findex[i] = imce.fids[fid] = imce.tbody.insertRow(i);
-    for (var i in attr) row.insertCell(i).className = attr[i];
-  }
-  row.cells[0].innerHTML = row.id = fid;
-  row.cells[1].innerHTML = file.fsize; row.cells[1].id = file.size;
-  row.cells[2].innerHTML = file.width;
-  row.cells[3].innerHTML = file.height;
-  row.cells[4].innerHTML = file.fdate; row.cells[4].id = file.date;
-  imce.invoke('list', row);
-  if (imce.vars.prvfid == fid) imce.setPreview(fid);
-  if (file.id) imce.urlId[imce.getURL(fid)] = file.id;
-},
-
-//remove a file from the list
-fileRemove: function(fid) {
-  if (!(row = imce.fids[fid])) return;
-  imce.fileDeSelect(fid);
-  imce.findex.splice(row.rowIndex, 1);
-  $(row).remove();
-  delete imce.fids[fid];
-  if (imce.vars.prvfid == fid) imce.setPreview();
-},
-
-//return a file object containing all properties.
-fileGet: function (fid) {
-  var row = imce.fids[fid];
-  var url = imce.getURL(fid);
-  return row ? {
-    name: imce.decode(fid),
-    url: url,
-    size: row.cells[1].innerHTML,
-    bytes: row.cells[1].id * 1,
-    width: row.cells[2].innerHTML * 1,
-    height: row.cells[3].innerHTML * 1,
-    date: row.cells[4].innerHTML,
-    time: row.cells[4].id * 1,
-    id: imce.urlId[url] || 0, //file id for newly uploaded files
-    relpath: (imce.conf.dir == '.' ? '' : imce.conf.dir +'/') + fid //rawurlencoded path relative to file directory path.
-  } : null;
-},
-
-//simulate row click. selection-highlighting
-fileClick: function(row, ctrl, shft) {
-  if (!row) return;
-  var fid = typeof(row) == 'string' ? row : row.id;
-  if (ctrl || fid == imce.vars.prvfid) {
-    imce.fileToggleSelect(fid);
-  }
-  else if (shft) {
-    var last = imce.lastFid();
-    var start = last ? imce.fids[last].rowIndex : -1;
-    var end = imce.fids[fid].rowIndex;
-    var step = start > end ? -1 : 1;
-    while (start != end) {
-      start += step;
-      imce.fileSelect(imce.findex[start].id);
-    }
-  }
-  else {
-    for (var fname in imce.selected) {
-      imce.fileDeSelect(fname);
-    }
-    imce.fileSelect(fid);
-  }
-  //set preview
-  imce.setPreview(imce.selcount == 1 ? imce.lastFid() : null);
-},
-
-//file select/deselect functions
-fileSelect: function (fid) {
-  if (imce.selected[fid] || !imce.fids[fid]) return;
-  imce.selected[fid] = imce.fids[imce.vars.lastfid=fid];
-  $(imce.selected[fid]).addClass('selected');
-  imce.selcount++;
-},
-fileDeSelect: function (fid) {
-  if (!imce.selected[fid] || !imce.fids[fid]) return;
-  if (imce.vars.lastfid == fid) imce.vars.lastfid = null;
-  $(imce.selected[fid]).removeClass('selected');
-  delete imce.selected[fid];
-  imce.selcount--;
-},
-fileToggleSelect: function (fid) {
-  imce['file'+ (imce.selected[fid] ? 'De' : '') +'Select'](fid);
-},
-
-/**************** OPERATIONS ********************/
-
-//process file operation form and create operation tabs.
-initiateOps: function() {
-  imce.setHtmlOps();
-  imce.setUploadOp();//upload
-  imce.setFileOps();//thumb, delete, resize
-},
-
-//process existing html ops.
-setHtmlOps: function () {
-  $(imce.el('ops-list')).children('li').each(function() {
-    if (!this.firstChild) return $(this).remove();
-    var name = this.id.substr(8);
-    var Op = imce.ops[name] = {div: imce.el('op-content-'+ name), li: imce.el('op-item-'+ name)};
-    Op.a = Op.li.firstChild;
-    Op.title = Op.a.innerHTML;
-    $(Op.a).click(function() {imce.opClick(name); return false;});
-  });
-},
-
-//convert upload form to an op.
-setUploadOp: function () {
-  var form = imce.el('imce-upload-form');
-  if (!form) return;
-  $(form).ajaxForm(imce.uploadSettings()).find('fieldset').each(function() {//clean up fieldsets
-    this.removeChild(this.firstChild);
-    $(this).after(this.childNodes);
-  }).remove();
-  imce.opAdd({name: 'upload', title: Drupal.t('Upload'), content: form});//add op
-},
-
-//convert fileop form submit buttons to ops.
-setFileOps: function () {
-  var form = imce.el('imce-fileop-form');
-  if (!form) return;
-  $(form.elements.filenames).parent().remove();
-  $(form).find('fieldset').each(function() {//remove fieldsets
-    var $sbmt = $('input:submit', this);
-    if (!$sbmt.size()) return;
-    var Op = {name: $sbmt.attr('id').substr(5)};
-    var func = function() {imce.fopSubmit(Op.name); return false;};
-    $sbmt.click(func);
-    Op.title = $(this).children('legend').remove().text();
-    Op.name == 'delete' ? (Op.func = func) : (Op.content = this.childNodes);
-    imce.opAdd(Op);
-  }).remove();
-  imce.vars.opform = $(form).serialize();//serialize remaining parts.
-},
-
-//refresh ops states. enable/disable
-refreshOps: function() {
-  for (var p in imce.conf.perm) {
-    if (imce.conf.perm[p]) imce.opEnable(p);
-    else imce.opDisable(p);
-  }
-},
-
-//add a new file operation
-opAdd: function (op) {
-  var oplist = imce.el('ops-list'), opcons = imce.el('op-contents');
-  var name = op.name || ('op-'+ $(oplist).children('li').size());
-  var Op = imce.ops[name] = {title: op.title || 'Untitled'};
-  if (op.content) {
-    Op.div = imce.newEl('div');
-    $(Op.div).attr({id: 'op-content-'+ name, 'class': 'op-content'}).appendTo(opcons).append(op.content);
-  }
-  Op.a = imce.newEl('a');
-  Op.li = imce.newEl('li');
-  $(Op.a).attr({href: '#', 'name': name}).html('<span>' + op.title +'</span>').click(imce.opClickEvent);
-  $(Op.li).attr('id', 'op-item-'+ op.name).append(Op.a).appendTo(oplist);
-  Op.func = op.func || imce.opVoid;
-  return Op;
-},
-
-//click event for file operations
-opClickEvent: function(e) {
-  imce.opClick(this.name);
-  return false;
-},
-
-//void operation function
-opVoid: function() {},
-
-//perform op click
-opClick: function(name) {
-  var Op = imce.ops[name], oldop = imce.vars.op;
-  if (!Op || Op.disabled) {
-    return imce.setMessage(Drupal.t('You can not perform this operation.'), 'error');
-  }
-  if (Op.div) {
-    if (oldop) {
-      var toggle = oldop == name;
-      imce.opShrink(oldop, toggle ? 'slideUp' : 'hide');
-      if (toggle) return false;
-    }
-    var left = Op.li.offsetLeft;
-    var $opcon = $('#op-contents').css({left: 0});
-    $(Op.div).slideDown('normal', function() {
-      setTimeout(function() {
-        if (imce.vars.op) {
-          var $inputs = $('input', imce.ops[imce.vars.op].div);
-          $inputs.eq(0).focus();
-          //form inputs become invisible in IE. Solution is as stupid as the behavior.
-          $('html').is('.ie') && $inputs.addClass('dummyie').removeClass('dummyie');
-       }
-      });
-    });
-    var diff = left + $opcon.width() - $('#imce-content').width();
-    $opcon.css({left: diff > 0 ? left - diff : left});
-    $(Op.li).addClass('active');
-    $(imce.opCloseLink).css('visibility', 'visible');
-    imce.vars.op = name;
-  }
-  Op.func(true);
-  return true;
-},
-
-//enable a file operation
-opEnable: function(name) {
-  var Op = imce.ops[name];
-  if (Op && Op.disabled) {
-    Op.disabled = false;
-    $(Op.li).show();
-  }
-},
-
-//disable a file operation
-opDisable: function(name) {
-  var Op = imce.ops[name];
-  if (Op && !Op.disabled) {
-    Op.div && imce.opShrink(name);
-    $(Op.li).hide();
-    Op.disabled = true;
-  }
-},
-
-//hide contents of a file operation
-opShrink: function(name, effect) {
-  if (imce.vars.op != name) return;
-  var Op = imce.ops[name];
-  $(Op.div).stop(true, true)[effect || 'hide']();
-  $(Op.li).removeClass('active');
-  $(imce.opCloseLink).css('visibility', 'hidden');
-  Op.func(false);
-  imce.vars.op = null;
-},
-
-/**************** AJAX OPERATIONS  ********************/
-
-//navigate to dir
-navigate: function(dir) {
-  if (imce.vars.navbusy || (dir == imce.conf.dir && !confirm(Drupal.t('Do you want to refresh the current directory?')))) return;
-  var cache = imce.vars.cache && dir != imce.conf.dir;
-  var set = imce.navSet(dir, cache);
-  if (cache && imce.cache[dir]) {//load from the cache
-    set.success({data: imce.cache[dir]});
-    set.complete();
-  }
-  else $.ajax(set);//live load
-},
-//ajax navigation settings
-navSet: function (dir, cache) {
-  $(imce.tree[dir].li).addClass('loading');
-  imce.vars.navbusy = dir;
-  return {url: imce.ajaxURL('navigate', dir),
-  type: 'GET',
-  dataType: 'json',
-  success: function(response) {
-    if (response.data && !response.data.error) {
-      if (cache) imce.navCache(imce.conf.dir, dir);//cache the current dir
-      imce.navUpdate(response.data, dir);
-    }
-    imce.processResponse(response);
-  },
-  complete: function () {
-    $(imce.tree[dir].li).removeClass('loading');
-    imce.vars.navbusy = null;
-  }
-  };
-},
-
-//update directory using the given data
-navUpdate: function(data, dir) {
-  var cached = data == imce.cache[dir], olddir = imce.conf.dir;
-  if (cached) data.files.id = 'file-list';
-  $(imce.FLW).html(data.files);
-  imce.dirActivate(dir);
-  imce.dirSubdirs(dir, data.subdirectories);
-  $.extend(imce.conf.perm, data.perm);
-  imce.refreshOps();
-  imce.initiateList(cached);
-  imce.setPreview(imce.selcount == 1 ? imce.lastFid() : null);
-  imce.SBW.scrollTop = 0;
-  imce.invoke('navigate', data, olddir, cached);
-},
-
-//set cache
-navCache: function (dir, newdir) {
-  var C = imce.cache[dir] = {'dir': dir, files: imce.el('file-list'), dirsize: imce.el('dir-size').innerHTML, perm: $.extend({}, imce.conf.perm)};
-  C.files.id = 'cached-list-'+ dir;
-  imce.el('forms-wrapper').appendChild(C.files);
-  imce.invoke('cache', C, newdir);
-},
-
-/**************** UPLOAD  ********************/
-//validate upload form
-uploadValidate: function (data, form, options) {
-  var path = data[0].value;
-  if (!path) return false;
-  if (imce.conf.extensions != '*') {
-    var ext = path.substr(path.lastIndexOf('.') + 1);
-    if ((' '+ imce.conf.extensions +' ').indexOf(' '+ ext.toLowerCase() +' ') == -1) {
-      return imce.setMessage(Drupal.t('Only files with the following extensions are allowed: %files-allowed.', {'%files-allowed': imce.conf.extensions}), 'error');
-    }
-  }
-  var sep = path.indexOf('/') == -1 ? '\\' : '/';
-  options.url = imce.ajaxURL('upload');//make url contain current dir.
-  imce.fopLoading('upload', true);
-  return true;
-},
-
-//settings for upload
-uploadSettings: function () {
-  return {beforeSubmit: imce.uploadValidate, success: function (response) {imce.processResponse(Drupal.parseJson(response));}, complete: function () {imce.fopLoading('upload', false);}, resetForm: true};
-},
-
-/**************** FILE OPS  ********************/
-//validate default ops(delete, thumb, resize)
-fopValidate: function(fop) {
-  if (!imce.validateSelCount(1, imce.conf.filenum)) return false;
-  switch (fop) {
-    case 'delete':
-      return confirm(Drupal.t('Delete selected files?'));
-    case 'thumb':
-      if (!$('input:checked', imce.ops['thumb'].div).size()) {
-        return imce.setMessage(Drupal.t('Please select a thumbnail.'), 'error');
-      }
-      return imce.validateImage();
-    case 'resize':
-      var w = imce.el('edit-width').value, h = imce.el('edit-height').value;
-      var maxDim = imce.conf.dimensions.split('x');
-      var maxW = maxDim[0]*1, maxH = maxW ? maxDim[1]*1 : 0;
-      if (!(/^[1-9][0-9]*$/).test(w) || !(/^[1-9][0-9]*$/).test(h) || (maxW && (maxW < w*1 || maxH < h*1))) {
-        return imce.setMessage(Drupal.t('Please specify dimensions within the allowed range that is from 1x1 to @dimensions.', {'@dimensions': maxW ? imce.conf.dimensions : Drupal.t('unlimited')}), 'error');
-      }
-      return imce.validateImage();
-  }
-
-  var func = fop +'OpValidate';
-  if (imce[func]) return imce[func](fop);
-  return true;
-},
-
-//submit wrapper for default ops
-fopSubmit: function(fop) {
-  switch (fop) {
-    case 'thumb': case 'delete': case 'resize':  return imce.commonSubmit(fop);
-  }
-  var func = fop +'OpSubmit';
-  if (imce[func]) return imce[func](fop);
-},
-
-//common submit function shared by default ops
-commonSubmit: function(fop) {
-  if (!imce.fopValidate(fop)) return false;
-  imce.fopLoading(fop, true);
-  $.ajax(imce.fopSettings(fop));
-},
-
-//settings for default file operations
-fopSettings: function (fop) {
-  return {url: imce.ajaxURL(fop), type: 'POST', dataType: 'json', success: imce.processResponse, complete: function (response) {imce.fopLoading(fop, false);}, data: imce.vars.opform +'&filenames='+ imce.serialNames() +'&jsop='+ fop + (imce.ops[fop].div ? '&'+ $('input, select, textarea', imce.ops[fop].div).serialize() : '')};
-},
-
-//toggle loading state
-fopLoading: function(fop, state) {
-  var el = imce.el('edit-'+ fop), func = state ? 'addClass' : 'removeClass'
-  if (el) {
-    $(el)[func]('loading').attr('disabled', state);
-  }
-  else {
-    $(imce.ops[fop].li)[func]('loading');
-    imce.ops[fop].disabled = state;
-  }
-},
-
-/**************** PREVIEW & SEND TO  ********************/
-
-//preview a file.
-setPreview: function (fid) {
-  var row, html = '';
-  imce.vars.prvfid = fid;
-  if (fid && (row = imce.fids[fid])) {
-    var width = row.cells[2].innerHTML * 1;
-    html = imce.vars.previewImages && width ? imce.imgHtml(fid, width, row.cells[3].innerHTML) : imce.decode(fid);
-    html = '<a href="#" onclick="imce.send(\''+ fid +'\'); return false;" title="'+ (imce.vars.prvtitle||'') +'">'+ html +'</a>';
-  }
-  imce.el('file-preview').innerHTML = html;
-},
-
-//default file send function. sends the file to the new window.
-send: function (fid) {
-  fid && window.open(imce.getURL(fid));
-},
-
-//add an operation for an external application to which the files are send.
-setSendTo: function (title, func) {
-  imce.send = function (fid) { fid && func(imce.fileGet(fid), window);};
-  var opFunc = function () {
-    if (imce.selcount != 1) return imce.setMessage(Drupal.t('Please select a file.'), 'error');
-    imce.send(imce.vars.prvfid);
-  };
-  imce.vars.prvtitle = title;
-  return imce.opAdd({name: 'sendto', title: title, func: opFunc});
-},
-
-/**************** LOG MESSAGES  ********************/
-
-//move initial page messages into log
-prepareMsgs: function () {
-  var msgs;
-  if (msgs = imce.el('imce-messages')) {
-    $('>div', msgs).each(function (){
-      var type = this.className.split(' ')[1];
-      var li = $('>ul li', this);
-      if (li.size()) li.each(function () {imce.setMessage(this.innerHTML, type);});
-      else imce.setMessage(this.innerHTML, type);
-    });
-    $(msgs).remove();
-  }
-},
-
-//insert log message
-setMessage: function (msg, type) {
-  var $box = $(imce.msgBox);
-  var logs = imce.el('log-messages') || $(imce.newEl('div')).appendTo('#help-box-content').before('<h4>'+ Drupal.t('Log messages') +':</h4>').attr('id', 'log-messages')[0];
-  var msg = '<div class="message '+ (type || 'status') +'">'+ msg +'</div>';
-  $box.queue(function() {
-    $box.css({opacity: 0, display: 'block'}).html(msg);
-    $box.dequeue();
-  });
-  $box.fadeTo(600, 1).fadeTo(1000, 1).fadeOut(400);
-  $(logs).append(msg);
-  return false;
-},
-
-/**************** OTHER HELPER FUNCTIONS  ********************/
-//invoke hooks
-invoke: function (hook) {
-  var i, args, func, funcs;
-  if ((funcs = imce.hooks[hook]) && funcs.length) {
-    (args = $.makeArray(arguments)).shift();
-    for (i = 0; func = funcs[i]; i++) func.apply(this, args);
-  }
-},
-
-//process response
-processResponse: function (response) {
-  if (response.data) imce.resData(response.data);
-  if (response.messages) imce.resMsgs(response.messages);
-},
-//process response data
-resData: function (data) {
-  var i, added, removed;
-  if (added = data.added) {
-    var cnt = imce.findex.length;
-    for (i in added) {//add new files or update existing
-      imce.fileAdd(added[i]);
-    }
-    if (added.length == 1) {//if it is a single file operation
-      imce.highlight(added[0].name);//highlight
-    }
-    if (imce.findex.length != cnt) {//if new files added, scroll to bottom.
-      $(imce.SBW).animate({scrollTop: imce.SBW.scrollHeight}).focus();
-    }
-  }
-  if (removed = data.removed) for (i in removed) {
-    imce.fileRemove(removed[i]);
-  }
-  imce.conf.dirsize = data.dirsize;
-  imce.updateStat();
-},
-//set response messages
-resMsgs: function (msgs) {
-  for (var type in msgs) for (var i in msgs[type]) {
-    imce.setMessage(msgs[type][i], type);
-  }
-},
-
-//return img markup
-imgHtml: function (fid, width, height) {
-  return '<img src="'+ imce.getURL(fid) +'" width="'+ width +'" height="'+ height +'" alt="'+ imce.decode(fid) +'">';
-},
-//check if the file is an image
-isImage: function (fid) {
-  return imce.fids[fid].cells[2].innerHTML * 1;
-},
-//find the first non-image in the selection
-getNonImage: function (selected) {
-  for (var fid in selected) {
-    if (!imce.isImage(fid)) return fid;
-  }
-  return false;
-},
-//validate current selection for images
-validateImage: function () {
-  var nonImg = imce.getNonImage(imce.selected);
-  return nonImg ? imce.setMessage(Drupal.t('%filename is not an image.', {'%filename': imce.decode(nonImg)}), 'error') : true;
-},
-//validate number of selected files
-validateSelCount: function (Min, Max) {
-  if (Min && imce.selcount < Min) {
-    return imce.setMessage(Min == 1 ? Drupal.t('Please select a file.') : Drupal.t('You must select at least %num files.', {'%num': Min}), 'error');
-  }
-  if (Max && Max < imce.selcount) {
-    return imce.setMessage(Drupal.t('You are not allowed to operate on more than %num files.', {'%num': Max}), 'error');
-  }
-  return true;
-},
-
-//update file count and dir size
-updateStat: function () {
-  imce.el('file-count').innerHTML = imce.findex.length;
-  imce.el('dir-size').innerHTML = imce.conf.dirsize;
-},
-//serialize selected files. return fids with a colon between them
-serialNames: function () {
-  var str = '';
-  for (var fid in imce.selected) {
-    str += ':'+ fid;
-  }
-  return str.substr(1);
-},
-//get file url. re-encode & and # for mod rewrite
-getURL: function (fid) {
-  var path = (imce.conf.dir == '.' ? '' : imce.conf.dir +'/') + fid;
-  return imce.conf.furl + (imce.conf.modfix ? path.replace(/%(23|26)/g, '%25$1') : path);
-},
-//el. by id
-el: function (id) {
-  return document.getElementById(id);
-},
-//find the latest selected fid
-lastFid: function () {
-  if (imce.vars.lastfid) return imce.vars.lastfid;
-  for (var fid in imce.selected);
-  return fid;
-},
-//create ajax url
-ajaxURL: function (op, dir) {
-  return imce.conf.url + (imce.conf.clean ? '?' :'&') +'jsop='+ op +'&dir='+ (dir||imce.conf.dir);
-},
-//fast class check
-hasC: function (el, name) {
-  return el.className && (' '+ el.className +' ').indexOf(' '+ name +' ') != -1;
-},
-//highlight a single file
-highlight: function (fid) {
-  if (imce.vars.prvfid) imce.fileClick(imce.vars.prvfid);
-  imce.fileClick(fid);
-},
-//process a row
-processRow: function (row) {
-  row.cells[0].innerHTML = imce.decode(row.id);
-  row.onmousedown = function(e) {
-    var e = e||window.event;
-    imce.fileClick(this, e.ctrlKey, e.shiftKey);
-    return !(e.ctrlKey || e.shiftKey);
-  };
-  row.ondblclick = function(e) {
-    imce.send(this.id);
-    return false;
-  };
-},
-//decode urls. uses unescape. can be overridden to use decodeURIComponent
-decode: function (str) {
-  return unescape(str);
-},
-//global ajax error function
-ajaxError: function (e, response, settings, thrown) {
-  imce.setMessage(Drupal.ahahError(response, settings.url).replace(/\n/g, '<br />'), 'error');
-},
-//convert button elements to standard input buttons
-convertButtons: function(form) {
-  $('button:submit', form).each(function(){
-    $(this).replaceWith('<input type="submit" value="'+ $(this).text() +'" name="'+ this.name +'" class="form-submit" id="'+ this.id +'" />');
-  });
-},
-//create element
-newEl: function(name) {
-  return document.createElement(name);
-},
-//scroll syncronization for section headers
-syncScroll: function(scrlEl, fixEl, bottom) {
-  var $fixEl = $(fixEl);
-  var prop = bottom ? 'bottom' : 'top';
-  var factor = bottom ? -1 : 1;
-  var syncScrl = function(el) {
-    $fixEl.css(prop, factor * el.scrollTop);
-  }
-  $(scrlEl).scroll(function() {
-    var el = this;
-    syncScrl(el);
-    setTimeout(function() {
-      syncScrl(el);
-    });
-  });
-},
-//get UI ready. provide backward compatibility.
-updateUI: function() {
-  //file urls.
-  var furl = imce.conf.furl, isabs = furl.indexOf('://') > -1;
-  var absurls = imce.conf.absurls = imce.vars.absurls || imce.conf.absurls;
-  var host = location.host;
-  var baseurl = location.protocol + '//' + host;
-  if (furl.charAt(furl.length - 1) != '/') {
-    furl += '/';
-  }
-  imce.conf.modfix = imce.conf.clean && furl.indexOf(host + '/system/') > -1;
-  if (absurls && !isabs) {
-    imce.conf.furl = baseurl + furl;
-  }
-  else if (!absurls && isabs && furl.indexOf(baseurl) == 0) {
-    imce.conf.furl = furl.substr(baseurl.length);
-  }
-  //convert button elements to input elements.
-  imce.convertButtons(imce.el('forms-wrapper'));
-  //ops-list
-  $('#ops-list').removeClass('tabs secondary').addClass('clear-block clearfix');
-  imce.opCloseLink = $(imce.newEl('a')).attr({id: 'op-close-link', href: '#', title: Drupal.t('Close')}).click(function() {
-    imce.vars.op && imce.opClick(imce.vars.op);
-    return false;
-  }).appendTo('#op-contents')[0];
-  //navigation-header
-  if (!$('#navigation-header').size()) {
-    $('#navigation-wrapper > .navigation-text').attr('id', 'navigation-header').wrapInner('<span></span>');
-  }
-  //log
-  $('#log-prv-wrapper').before($('#log-prv-wrapper > #preview-wrapper')).remove();
-  $('#log-clearer').remove();
-  //content resizer
-  $('#content-resizer').remove();
-  //message-box
-  imce.msgBox = imce.el('message-box') || $('<div id="message-box"></div>').prependTo('#imce-content')[0];
-  //help box & ie fix
-  var $hbox = $('#help-box');
-  $hbox.is('a') && $hbox.replaceWith($(imce.newEl('div')).attr('id', 'help-box').append($hbox.children()));
-  var $htitle = $('#help-box-title');
-  if ($.browser.msie) {
-    $('html').addClass('ie');
-    if (parseFloat($.browser.version) < 8) {
-      var $hcontent = $('#help-box-content');
-      $hcontent.add($htitle).hover(function() {
-        $hcontent.addClass('hover');
-      }, function() {
-        $hcontent.removeClass('hover');
-      });
-      $('html').addClass('ie-7');
-    }
-  }
-  !$htitle.children('span').size() && $htitle.wrapInner('<span></span>');
-  //scrolling file list
-  imce.syncScroll(imce.SBW, '#file-header-wrapper');
-  imce.syncScroll(imce.SBW, '#dir-stat', true);
-  //scrolling directory tree
-  imce.syncScroll('#navigation-wrapper', '#navigation-header');
-}
-};
-
-//initiate
-$(document).ready(imce.initiate).ajaxError(imce.ajaxError);
-
+// $Id: imce.js,v 1.2 2010/08/31 16:36:17 c0aslm1 Exp $
+
+(function($) {
+//Global container.
+window.imce = {tree: {}, findex: [], fids: {}, selected: {}, selcount: 0, ops: {}, cache: {}, urlId: {},
+vars: {previewImages: 1, cache: 1},
+hooks: {load: [], list: [], navigate: [], cache: []},
+
+//initiate imce.
+initiate: function() {
+  imce.conf = Drupal.settings.imce || {};
+  if (imce.conf.error != false) return;
+  imce.FLW = imce.el('file-list-wrapper');
+  imce.SBW = imce.el('sub-browse-wrapper');
+  imce.updateUI();
+  imce.prepareMsgs();//process initial status messages
+  imce.initiateTree();//build directory tree
+  imce.hooks.list.unshift(imce.processRow);//set the default list-hook.
+  imce.initiateList();//process file list
+  imce.initiateOps();//prepare operation tabs
+  imce.refreshOps();
+  imce.invoke('load', window);//run functions set by external applications.
+},
+
+/**************** DIRECTORIES ********************/
+
+//process navigation tree
+initiateTree: function() {
+  $('#navigation-tree li').each(function(i) {
+    var a = this.firstChild, txt = a.firstChild;
+    txt && (txt.data = imce.decode(txt.data));
+    var branch = imce.tree[a.title] = {'a': a, li: this, ul: this.lastChild.tagName == 'UL' ? this.lastChild : null};
+    if (a.href) imce.dirClickable(branch);
+    imce.dirCollapsible(branch);
+  });
+},
+
+//Add a dir to the tree under parent
+dirAdd: function(dir, parent, clickable) {
+  if (imce.tree[dir]) return clickable ? imce.dirClickable(imce.tree[dir]) : imce.tree[dir];
+  var parent = parent || imce.tree['.'];
+  parent.ul = parent.ul ? parent.ul : parent.li.appendChild(imce.newEl('ul'));
+  var branch = imce.dirCreate(dir, imce.decode(dir.substr(dir.lastIndexOf('/')+1)), clickable);
+  parent.ul.appendChild(branch.li);
+  return branch;
+},
+
+//create list item for navigation tree
+dirCreate: function(dir, text, clickable) {
+  if (imce.tree[dir]) return imce.tree[dir];
+  var branch = imce.tree[dir] = {li: imce.newEl('li'), a: imce.newEl('a')};
+  $(branch.a).addClass('folder').text(text).attr('title', dir).appendTo(branch.li);
+  imce.dirCollapsible(branch);
+  return clickable ? imce.dirClickable(branch) : branch;
+},
+
+//change currently active directory
+dirActivate: function(dir) {
+  if (dir != imce.conf.dir) {
+    if (imce.tree[imce.conf.dir]){
+      $(imce.tree[imce.conf.dir].a).removeClass('active');
+    }
+    $(imce.tree[dir].a).addClass('active');
+    imce.conf.dir = dir;
+  }
+  return imce.tree[imce.conf.dir];
+},
+
+//make a dir accessible
+dirClickable: function(branch) {
+  if (branch.clkbl) return branch;
+  $(branch.a).attr('href', '#').removeClass('disabled').click(function() {imce.navigate(this.title); return false;});
+  branch.clkbl = true;
+  return branch;
+},
+
+//sub-directories expand-collapse ability
+dirCollapsible: function (branch) {
+  if (branch.clpsbl) return branch;
+  $(imce.newEl('span')).addClass('expander').html('&nbsp;').click(function() {
+    if (branch.ul) {
+      $(branch.ul).toggle();
+      $(branch.li).toggleClass('expanded');
+    }
+    else if (branch.clkbl){
+      $(branch.a).click();
+    }
+  }).prependTo(branch.li);
+  branch.clpsbl = true;
+  return branch;
+},
+
+//update navigation tree after getting subdirectories.
+dirSubdirs: function(dir, subdirs) {
+  var branch = imce.tree[dir];
+  if (subdirs && subdirs.length) {
+    var prefix = dir == '.' ? '' : dir +'/';
+    for (var i in subdirs) {//add subdirectories
+      imce.dirAdd(prefix + subdirs[i], branch, true);
+    }
+    $(branch.li).removeClass('leaf').addClass('expanded');
+    $(branch.ul).show();
+  }
+  else if (!branch.ul){//no subdirs->leaf
+    $(branch.li).removeClass('expanded').addClass('leaf');
+  }
+},
+
+/**************** FILES ********************/
+
+//process file list
+initiateList: function(cached) {
+  var L = imce.hooks.list, dir = imce.conf.dir, token = {'%dir':  dir == '.' ? $(imce.tree['.'].a).text() : imce.decode(dir)}
+  imce.findex = [], imce.fids = {}, imce.selected = {}, imce.selcount = 0, imce.vars.lastfid = null;
+  imce.tbody = imce.el('file-list').tBodies[0];
+  if (imce.tbody.rows.length) {
+    for (var row, i = 0; row = imce.tbody.rows[i]; i++) {
+      var fid = row.id;
+      imce.findex[i] = imce.fids[fid] = row;
+      if (cached) {
+        if (imce.hasC(row, 'selected')) {
+          imce.selected[imce.vars.lastfid = fid] = row;
+          imce.selcount++;
+        }
+      }
+      else {
+        for (var func, j = 0; func = L[j]; j++) func(row);//invoke list-hook
+      }
+    }
+  }
+  if (!imce.conf.perm.browse) {
+    imce.setMessage(Drupal.t('File browsing is disabled in directory %dir.', token), 'error');
+  }
+},
+
+//add a file to the list. (having properties name,size,formatted size,width,height,date,formatted date)
+fileAdd: function(file) {
+  var row, fid = file.name, i = imce.findex.length, attr = ['name', 'size', 'width', 'height', 'date'];
+  if (!(row = imce.fids[fid])) {
+    row = imce.findex[i] = imce.fids[fid] = imce.tbody.insertRow(i);
+    for (var i in attr) row.insertCell(i).className = attr[i];
+  }
+  row.cells[0].innerHTML = row.id = fid;
+  row.cells[1].innerHTML = file.fsize; row.cells[1].id = file.size;
+  row.cells[2].innerHTML = file.width;
+  row.cells[3].innerHTML = file.height;
+  row.cells[4].innerHTML = file.fdate; row.cells[4].id = file.date;
+  imce.invoke('list', row);
+  if (imce.vars.prvfid == fid) imce.setPreview(fid);
+  if (file.id) imce.urlId[imce.getURL(fid)] = file.id;
+},
+
+//remove a file from the list
+fileRemove: function(fid) {
+  if (!(row = imce.fids[fid])) return;
+  imce.fileDeSelect(fid);
+  imce.findex.splice(row.rowIndex, 1);
+  $(row).remove();
+  delete imce.fids[fid];
+  if (imce.vars.prvfid == fid) imce.setPreview();
+},
+
+//return a file object containing all properties.
+fileGet: function (fid) {
+  var row = imce.fids[fid];
+  var url = imce.getURL(fid);
+  return row ? {
+    name: imce.decode(fid),
+    url: url,
+    size: row.cells[1].innerHTML,
+    bytes: row.cells[1].id * 1,
+    width: row.cells[2].innerHTML * 1,
+    height: row.cells[3].innerHTML * 1,
+    date: row.cells[4].innerHTML,
+    time: row.cells[4].id * 1,
+    id: imce.urlId[url] || 0, //file id for newly uploaded files
+    relpath: (imce.conf.dir == '.' ? '' : imce.conf.dir +'/') + fid //rawurlencoded path relative to file directory path.
+  } : null;
+},
+
+//simulate row click. selection-highlighting
+fileClick: function(row, ctrl, shft) {
+  if (!row) return;
+  var fid = typeof(row) == 'string' ? row : row.id;
+  if (ctrl || fid == imce.vars.prvfid) {
+    imce.fileToggleSelect(fid);
+  }
+  else if (shft) {
+    var last = imce.lastFid();
+    var start = last ? imce.fids[last].rowIndex : -1;
+    var end = imce.fids[fid].rowIndex;
+    var step = start > end ? -1 : 1;
+    while (start != end) {
+      start += step;
+      imce.fileSelect(imce.findex[start].id);
+    }
+  }
+  else {
+    for (var fname in imce.selected) {
+      imce.fileDeSelect(fname);
+    }
+    imce.fileSelect(fid);
+  }
+  //set preview
+  imce.setPreview(imce.selcount == 1 ? imce.lastFid() : null);
+},
+
+//file select/deselect functions
+fileSelect: function (fid) {
+  if (imce.selected[fid] || !imce.fids[fid]) return;
+  imce.selected[fid] = imce.fids[imce.vars.lastfid=fid];
+  $(imce.selected[fid]).addClass('selected');
+  imce.selcount++;
+},
+fileDeSelect: function (fid) {
+  if (!imce.selected[fid] || !imce.fids[fid]) return;
+  if (imce.vars.lastfid == fid) imce.vars.lastfid = null;
+  $(imce.selected[fid]).removeClass('selected');
+  delete imce.selected[fid];
+  imce.selcount--;
+},
+fileToggleSelect: function (fid) {
+  imce['file'+ (imce.selected[fid] ? 'De' : '') +'Select'](fid);
+},
+
+/**************** OPERATIONS ********************/
+
+//process file operation form and create operation tabs.
+initiateOps: function() {
+  imce.setHtmlOps();
+  imce.setUploadOp();//upload
+  imce.setFileOps();//thumb, delete, resize
+},
+
+//process existing html ops.
+setHtmlOps: function () {
+  $(imce.el('ops-list')).children('li').each(function() {
+    if (!this.firstChild) return $(this).remove();
+    var name = this.id.substr(8);
+    var Op = imce.ops[name] = {div: imce.el('op-content-'+ name), li: imce.el('op-item-'+ name)};
+    Op.a = Op.li.firstChild;
+    Op.title = Op.a.innerHTML;
+    $(Op.a).click(function() {imce.opClick(name); return false;});
+  });
+},
+
+//convert upload form to an op.
+setUploadOp: function () {
+  var form = imce.el('imce-upload-form');
+  if (!form) return;
+  $(form).ajaxForm(imce.uploadSettings()).find('fieldset').each(function() {//clean up fieldsets
+    this.removeChild(this.firstChild);
+    $(this).after(this.childNodes);
+  }).remove();
+  imce.opAdd({name: 'upload', title: Drupal.t('Upload'), content: form});//add op
+},
+
+//convert fileop form submit buttons to ops.
+setFileOps: function () {
+  var form = imce.el('imce-fileop-form');
+  if (!form) return;
+  $(form.elements.filenames).parent().remove();
+  $(form).find('fieldset').each(function() {//remove fieldsets
+    var $sbmt = $('input:submit', this);
+    if (!$sbmt.size()) return;
+    var Op = {name: $sbmt.attr('id').substr(5)};
+    var func = function() {imce.fopSubmit(Op.name); return false;};
+    $sbmt.click(func);
+    Op.title = $(this).children('legend').remove().text();
+    Op.name == 'delete' ? (Op.func = func) : (Op.content = this.childNodes);
+    imce.opAdd(Op);
+  }).remove();
+  imce.vars.opform = $(form).serialize();//serialize remaining parts.
+},
+
+//refresh ops states. enable/disable
+refreshOps: function() {
+  for (var p in imce.conf.perm) {
+    if (imce.conf.perm[p]) imce.opEnable(p);
+    else imce.opDisable(p);
+  }
+},
+
+//add a new file operation
+opAdd: function (op) {
+  var oplist = imce.el('ops-list'), opcons = imce.el('op-contents');
+  var name = op.name || ('op-'+ $(oplist).children('li').size());
+  var Op = imce.ops[name] = {title: op.title || 'Untitled'};
+  if (op.content) {
+    Op.div = imce.newEl('div');
+    $(Op.div).attr({id: 'op-content-'+ name, 'class': 'op-content'}).appendTo(opcons).append(op.content);
+  }
+  Op.a = imce.newEl('a');
+  Op.li = imce.newEl('li');
+  $(Op.a).attr({href: '#', 'name': name}).html('<span>' + op.title +'</span>').click(imce.opClickEvent);
+  $(Op.li).attr('id', 'op-item-'+ op.name).append(Op.a).appendTo(oplist);
+  Op.func = op.func || imce.opVoid;
+  return Op;
+},
+
+//click event for file operations
+opClickEvent: function(e) {
+  imce.opClick(this.name);
+  return false;
+},
+
+//void operation function
+opVoid: function() {},
+
+//perform op click
+opClick: function(name) {
+  var Op = imce.ops[name], oldop = imce.vars.op;
+  if (!Op || Op.disabled) {
+    return imce.setMessage(Drupal.t('You can not perform this operation.'), 'error');
+  }
+  if (Op.div) {
+    if (oldop) {
+      var toggle = oldop == name;
+      imce.opShrink(oldop, toggle ? 'slideUp' : 'hide');
+      if (toggle) return false;
+    }
+    var left = Op.li.offsetLeft;
+    var $opcon = $('#op-contents').css({left: 0});
+    $(Op.div).slideDown('normal', function() {
+      setTimeout(function() {
+        if (imce.vars.op) {
+          var $inputs = $('input', imce.ops[imce.vars.op].div);
+          $inputs.eq(0).focus();
+          //form inputs become invisible in IE. Solution is as stupid as the behavior.
+          $('html').is('.ie') && $inputs.addClass('dummyie').removeClass('dummyie');
+       }
+      });
+    });
+    var diff = left + $opcon.width() - $('#imce-content').width();
+    $opcon.css({left: diff > 0 ? left - diff : left});
+    $(Op.li).addClass('active');
+    $(imce.opCloseLink).css('visibility', 'visible');
+    imce.vars.op = name;
+  }
+  Op.func(true);
+  return true;
+},
+
+//enable a file operation
+opEnable: function(name) {
+  var Op = imce.ops[name];
+  if (Op && Op.disabled) {
+    Op.disabled = false;
+    $(Op.li).show();
+  }
+},
+
+//disable a file operation
+opDisable: function(name) {
+  var Op = imce.ops[name];
+  if (Op && !Op.disabled) {
+    Op.div && imce.opShrink(name);
+    $(Op.li).hide();
+    Op.disabled = true;
+  }
+},
+
+//hide contents of a file operation
+opShrink: function(name, effect) {
+  if (imce.vars.op != name) return;
+  var Op = imce.ops[name];
+  $(Op.div).stop(true, true)[effect || 'hide']();
+  $(Op.li).removeClass('active');
+  $(imce.opCloseLink).css('visibility', 'hidden');
+  Op.func(false);
+  imce.vars.op = null;
+},
+
+/**************** AJAX OPERATIONS  ********************/
+
+//navigate to dir
+navigate: function(dir) {
+  if (imce.vars.navbusy || (dir == imce.conf.dir && !confirm(Drupal.t('Do you want to refresh the current directory?')))) return;
+  var cache = imce.vars.cache && dir != imce.conf.dir;
+  var set = imce.navSet(dir, cache);
+  if (cache && imce.cache[dir]) {//load from the cache
+    set.success({data: imce.cache[dir]});
+    set.complete();
+  }
+  else $.ajax(set);//live load
+},
+//ajax navigation settings
+navSet: function (dir, cache) {
+  $(imce.tree[dir].li).addClass('loading');
+  imce.vars.navbusy = dir;
+  return {url: imce.ajaxURL('navigate', dir),
+  type: 'GET',
+  dataType: 'json',
+  success: function(response) {
+    if (response.data && !response.data.error) {
+      if (cache) imce.navCache(imce.conf.dir, dir);//cache the current dir
+      imce.navUpdate(response.data, dir);
+    }
+    imce.processResponse(response);
+  },
+  complete: function () {
+    $(imce.tree[dir].li).removeClass('loading');
+    imce.vars.navbusy = null;
+  }
+  };
+},
+
+//update directory using the given data
+navUpdate: function(data, dir) {
+  var cached = data == imce.cache[dir], olddir = imce.conf.dir;
+  if (cached) data.files.id = 'file-list';
+  $(imce.FLW).html(data.files);
+  imce.dirActivate(dir);
+  imce.dirSubdirs(dir, data.subdirectories);
+  $.extend(imce.conf.perm, data.perm);
+  imce.refreshOps();
+  imce.initiateList(cached);
+  imce.setPreview(imce.selcount == 1 ? imce.lastFid() : null);
+  imce.SBW.scrollTop = 0;
+  imce.invoke('navigate', data, olddir, cached);
+},
+
+//set cache
+navCache: function (dir, newdir) {
+  var C = imce.cache[dir] = {'dir': dir, files: imce.el('file-list'), dirsize: imce.el('dir-size').innerHTML, perm: $.extend({}, imce.conf.perm)};
+  C.files.id = 'cached-list-'+ dir;
+  imce.el('forms-wrapper').appendChild(C.files);
+  imce.invoke('cache', C, newdir);
+},
+
+/**************** UPLOAD  ********************/
+//check to see if the file being uploaded exists
+fileExistCheck: function(path) {
+  // check for slashes because IE includes entire filepath
+  if(path.lastIndexOf('\\') != -1){
+    var path = path.substr(path.lastIndexOf('\\') + 1);
+  }else{
+    var path = path;
+  }
+  var found = 0;
+  var file = $('#file-list tr td.name:contains(' + path + ')');
+  if(file.length > 0){
+    found = 1;
+  }
+  if(found == 1){
+    var answer = confirm(path + ' already exists.  Overwrite this file?');
+    if(answer == false){
+      return false;
+    } else{
+      return true;
+    }
+  }
+  return;
+},
+
+
+//validate upload form
+uploadValidate: function (data, form, options) {
+  var path = data[0].value;
+  if (!path) return false;
+  if(imce.upload_method == 1){
+    var exist = imce.fileExistCheck(path);
+    if (exist == false){
+      return false;
+    }
+  }
+  if (imce.conf.extensions != '*') {
+    var ext = path.substr(path.lastIndexOf('.') + 1);
+    if ((' '+ imce.conf.extensions +' ').indexOf(' '+ ext.toLowerCase() +' ') == -1) {
+      return imce.setMessage(Drupal.t('Only files with the following extensions are allowed: %files-allowed.', {'%files-allowed': imce.conf.extensions}), 'error');
+    }
+  }
+  var sep = path.indexOf('/') == -1 ? '\\' : '/';
+  options.url = imce.ajaxURL('upload');//make url contain current dir.
+  imce.fopLoading('upload', true);
+  return true;
+},
+
+//settings for upload
+uploadSettings: function () {
+  return {beforeSubmit: imce.uploadValidate, success: function (response) {imce.processResponse(Drupal.parseJson(response));}, complete: function () {imce.fopLoading('upload', false);}, resetForm: true};
+},
+
+/**************** FILE OPS  ********************/
+//validate default ops(delete, thumb, resize)
+fopValidate: function(fop) {
+  if (!imce.validateSelCount(1, imce.conf.filenum)) return false;
+  switch (fop) {
+    case 'delete':
+      return confirm(Drupal.t('Delete selected files?'));
+    case 'thumb':
+      if (!$('input:checked', imce.ops['thumb'].div).size()) {
+        return imce.setMessage(Drupal.t('Please select a thumbnail.'), 'error');
+      }
+      return imce.validateImage();
+    case 'resize':
+      var w = imce.el('edit-width').value, h = imce.el('edit-height').value;
+      var maxDim = imce.conf.dimensions.split('x');
+      var maxW = maxDim[0]*1, maxH = maxW ? maxDim[1]*1 : 0;
+      if (!(/^[1-9][0-9]*$/).test(w) || !(/^[1-9][0-9]*$/).test(h) || (maxW && (maxW < w*1 || maxH < h*1))) {
+        return imce.setMessage(Drupal.t('Please specify dimensions within the allowed range that is from 1x1 to @dimensions.', {'@dimensions': maxW ? imce.conf.dimensions : Drupal.t('unlimited')}), 'error');
+      }
+      return imce.validateImage();
+  }
+
+  var func = fop +'OpValidate';
+  if (imce[func]) return imce[func](fop);
+  return true;
+},
+
+//submit wrapper for default ops
+fopSubmit: function(fop) {
+  switch (fop) {
+    case 'thumb': case 'delete': case 'resize':  return imce.commonSubmit(fop);
+  }
+  var func = fop +'OpSubmit';
+  if (imce[func]) return imce[func](fop);
+},
+
+//common submit function shared by default ops
+commonSubmit: function(fop) {
+  if (!imce.fopValidate(fop)) return false;
+  imce.fopLoading(fop, true);
+  $.ajax(imce.fopSettings(fop));
+},
+
+//settings for default file operations
+fopSettings: function (fop) {
+  return {url: imce.ajaxURL(fop), type: 'POST', dataType: 'json', success: imce.processResponse, complete: function (response) {imce.fopLoading(fop, false);}, data: imce.vars.opform +'&filenames='+ imce.serialNames() +'&jsop='+ fop + (imce.ops[fop].div ? '&'+ $('input, select, textarea', imce.ops[fop].div).serialize() : '')};
+},
+
+//toggle loading state
+fopLoading: function(fop, state) {
+  var el = imce.el('edit-'+ fop), func = state ? 'addClass' : 'removeClass'
+  if (el) {
+    $(el)[func]('loading').attr('disabled', state);
+  }
+  else {
+    $(imce.ops[fop].li)[func]('loading');
+    imce.ops[fop].disabled = state;
+  }
+},
+
+/**************** PREVIEW & SEND TO  ********************/
+
+//preview a file.
+setPreview: function (fid) {
+  var row, html = '';
+  imce.vars.prvfid = fid;
+  if (fid && (row = imce.fids[fid])) {
+    var width = row.cells[2].innerHTML * 1;
+    html = imce.vars.previewImages && width ? imce.imgHtml(fid, width, row.cells[3].innerHTML) : imce.decode(fid);
+    html = '<a href="#" onclick="imce.send(\''+ fid +'\'); return false;" title="'+ (imce.vars.prvtitle||'') +'">'+ html +'</a>';
+  }
+  imce.el('file-preview').innerHTML = html;
+},
+
+//default file send function. sends the file to the new window.
+send: function (fid) {
+  fid && window.open(imce.getURL(fid));
+},
+
+//add an operation for an external application to which the files are send.
+setSendTo: function (title, func) {
+  imce.send = function (fid) { fid && func(imce.fileGet(fid), window);};
+  var opFunc = function () {
+    if (imce.selcount != 1) return imce.setMessage(Drupal.t('Please select a file.'), 'error');
+    imce.send(imce.vars.prvfid);
+  };
+  imce.vars.prvtitle = title;
+  return imce.opAdd({name: 'sendto', title: title, func: opFunc});
+},
+
+/**************** LOG MESSAGES  ********************/
+
+//move initial page messages into log
+prepareMsgs: function () {
+  var msgs;
+  if (msgs = imce.el('imce-messages')) {
+    $('>div', msgs).each(function (){
+      var type = this.className.split(' ')[1];
+      var li = $('>ul li', this);
+      if (li.size()) li.each(function () {imce.setMessage(this.innerHTML, type);});
+      else imce.setMessage(this.innerHTML, type);
+    });
+    $(msgs).remove();
+  }
+},
+
+//insert log message
+setMessage: function (msg, type) {
+  var $box = $(imce.msgBox);
+  var logs = imce.el('log-messages') || $(imce.newEl('div')).appendTo('#help-box-content').before('<h4>'+ Drupal.t('Log messages') +':</h4>').attr('id', 'log-messages')[0];
+  var msg = '<div class="message '+ (type || 'status') +'">'+ msg +'</div>';
+  $box.queue(function() {
+    $box.css({opacity: 0, display: 'block'}).html(msg);
+    $box.dequeue();
+  });
+  $box.fadeTo(600, 1).fadeTo(1000, 1).fadeOut(400);
+  $(logs).append(msg);
+  return false;
+},
+
+/**************** OTHER HELPER FUNCTIONS  ********************/
+//invoke hooks
+invoke: function (hook) {
+  var i, args, func, funcs;
+  if ((funcs = imce.hooks[hook]) && funcs.length) {
+    (args = $.makeArray(arguments)).shift();
+    for (i = 0; func = funcs[i]; i++) func.apply(this, args);
+  }
+},
+
+//process response
+processResponse: function (response) {
+  if (response.data) imce.resData(response.data);
+  if (response.messages) imce.resMsgs(response.messages);
+},
+//process response data
+resData: function (data) {
+  var i, added, removed;
+  if (added = data.added) {
+    var cnt = imce.findex.length;
+    for (i in added) {//add new files or update existing
+      imce.fileAdd(added[i]);
+    }
+    if (added.length == 1) {//if it is a single file operation
+      imce.highlight(added[0].name);//highlight
+    }
+    if (imce.findex.length != cnt) {//if new files added, scroll to bottom.
+      $(imce.SBW).animate({scrollTop: imce.SBW.scrollHeight}).focus();
+    }
+  }
+  if (removed = data.removed) for (i in removed) {
+    imce.fileRemove(removed[i]);
+  }
+  imce.conf.dirsize = data.dirsize;
+  imce.updateStat();
+},
+//set response messages
+resMsgs: function (msgs) {
+  for (var type in msgs) for (var i in msgs[type]) {
+    imce.setMessage(msgs[type][i], type);
+  }
+},
+
+//return img markup
+imgHtml: function (fid, width, height) {
+  return '<img src="'+ imce.getURL(fid) +'" width="'+ width +'" height="'+ height +'" alt="'+ imce.decode(fid) +'">';
+},
+//check if the file is an image
+isImage: function (fid) {
+  return imce.fids[fid].cells[2].innerHTML * 1;
+},
+//find the first non-image in the selection
+getNonImage: function (selected) {
+  for (var fid in selected) {
+    if (!imce.isImage(fid)) return fid;
+  }
+  return false;
+},
+//validate current selection for images
+validateImage: function () {
+  var nonImg = imce.getNonImage(imce.selected);
+  return nonImg ? imce.setMessage(Drupal.t('%filename is not an image.', {'%filename': imce.decode(nonImg)}), 'error') : true;
+},
+//validate number of selected files
+validateSelCount: function (Min, Max) {
+  if (Min && imce.selcount < Min) {
+    return imce.setMessage(Min == 1 ? Drupal.t('Please select a file.') : Drupal.t('You must select at least %num files.', {'%num': Min}), 'error');
+  }
+  if (Max && Max < imce.selcount) {
+    return imce.setMessage(Drupal.t('You are not allowed to operate on more than %num files.', {'%num': Max}), 'error');
+  }
+  return true;
+},
+
+//update file count and dir size
+updateStat: function () {
+  imce.el('file-count').innerHTML = imce.findex.length;
+  imce.el('dir-size').innerHTML = imce.conf.dirsize;
+},
+//serialize selected files. return fids with a colon between them
+serialNames: function () {
+  var str = '';
+  for (var fid in imce.selected) {
+    str += ':'+ fid;
+  }
+  return str.substr(1);
+},
+//get file url. re-encode & and # for mod rewrite
+getURL: function (fid) {
+  var path = (imce.conf.dir == '.' ? '' : imce.conf.dir +'/') + fid;
+  return imce.conf.furl + (imce.conf.modfix ? path.replace(/%(23|26)/g, '%25$1') : path);
+},
+//el. by id
+el: function (id) {
+  return document.getElementById(id);
+},
+//find the latest selected fid
+lastFid: function () {
+  if (imce.vars.lastfid) return imce.vars.lastfid;
+  for (var fid in imce.selected);
+  return fid;
+},
+//create ajax url
+ajaxURL: function (op, dir) {
+  return imce.conf.url + (imce.conf.clean ? '?' :'&') +'jsop='+ op +'&dir='+ (dir||imce.conf.dir);
+},
+//fast class check
+hasC: function (el, name) {
+  return el.className && (' '+ el.className +' ').indexOf(' '+ name +' ') != -1;
+},
+//highlight a single file
+highlight: function (fid) {
+  if (imce.vars.prvfid) imce.fileClick(imce.vars.prvfid);
+  imce.fileClick(fid);
+},
+//process a row
+processRow: function (row) {
+  row.cells[0].innerHTML = imce.decode(row.id);
+  row.onmousedown = function(e) {
+    var e = e||window.event;
+    imce.fileClick(this, e.ctrlKey, e.shiftKey);
+    return !(e.ctrlKey || e.shiftKey);
+  };
+  row.ondblclick = function(e) {
+    imce.send(this.id);
+    return false;
+  };
+},
+//decode urls. uses unescape. can be overridden to use decodeURIComponent
+decode: function (str) {
+  return unescape(str);
+},
+//global ajax error function
+ajaxError: function (e, response, settings, thrown) {
+  imce.setMessage(Drupal.ahahError(response, settings.url).replace(/\n/g, '<br />'), 'error');
+},
+//convert button elements to standard input buttons
+convertButtons: function(form) {
+  $('button:submit', form).each(function(){
+    $(this).replaceWith('<input type="submit" value="'+ $(this).text() +'" name="'+ this.name +'" class="form-submit" id="'+ this.id +'" />');
+  });
+},
+//create element
+newEl: function(name) {
+  return document.createElement(name);
+},
+//scroll syncronization for section headers
+syncScroll: function(scrlEl, fixEl, bottom) {
+  var $fixEl = $(fixEl);
+  var prop = bottom ? 'bottom' : 'top';
+  var factor = bottom ? -1 : 1;
+  var syncScrl = function(el) {
+    $fixEl.css(prop, factor * el.scrollTop);
+  }
+  $(scrlEl).scroll(function() {
+    var el = this;
+    syncScrl(el);
+    setTimeout(function() {
+      syncScrl(el);
+    });
+  });
+},
+//get UI ready. provide backward compatibility.
+updateUI: function() {
+  //file urls.
+  var furl = imce.conf.furl, isabs = furl.indexOf('://') > -1;
+  var absurls = imce.conf.absurls = imce.vars.absurls || imce.conf.absurls;
+  var host = location.host;
+  var baseurl = location.protocol + '//' + host;
+  if (furl.charAt(furl.length - 1) != '/') {
+    furl += '/';
+  }
+  imce.conf.modfix = imce.conf.clean && furl.indexOf(host + '/system/') > -1;
+  if (absurls && !isabs) {
+    imce.conf.furl = baseurl + furl;
+  }
+  else if (!absurls && isabs && furl.indexOf(baseurl) == 0) {
+    imce.conf.furl = furl.substr(baseurl.length);
+  }
+  //convert button elements to input elements.
+  imce.convertButtons(imce.el('forms-wrapper'));
+  //ops-list
+  $('#ops-list').removeClass('tabs secondary').addClass('clear-block clearfix');
+  imce.opCloseLink = $(imce.newEl('a')).attr({id: 'op-close-link', href: '#', title: Drupal.t('Close')}).click(function() {
+    imce.vars.op && imce.opClick(imce.vars.op);
+    return false;
+  }).appendTo('#op-contents')[0];
+  //navigation-header
+  if (!$('#navigation-header').size()) {
+    $('#navigation-wrapper > .navigation-text').attr('id', 'navigation-header').wrapInner('<span></span>');
+  }
+  //log
+  $('#log-prv-wrapper').before($('#log-prv-wrapper > #preview-wrapper')).remove();
+  $('#log-clearer').remove();
+  //content resizer
+  $('#content-resizer').remove();
+  //message-box
+  imce.msgBox = imce.el('message-box') || $('<div id="message-box"></div>').prependTo('#imce-content')[0];
+  //help box & ie fix
+  var $hbox = $('#help-box');
+  $hbox.is('a') && $hbox.replaceWith($(imce.newEl('div')).attr('id', 'help-box').append($hbox.children()));
+  var $htitle = $('#help-box-title');
+  if ($.browser.msie) {
+    $('html').addClass('ie');
+    if (parseFloat($.browser.version) < 8) {
+      var $hcontent = $('#help-box-content');
+      $hcontent.add($htitle).hover(function() {
+        $hcontent.addClass('hover');
+      }, function() {
+        $hcontent.removeClass('hover');
+      });
+      $('html').addClass('ie-7');
+    }
+  }
+  !$htitle.children('span').size() && $htitle.wrapInner('<span></span>');
+  //scrolling file list
+  imce.syncScroll(imce.SBW, '#file-header-wrapper');
+  imce.syncScroll(imce.SBW, '#dir-stat', true);
+  //scrolling directory tree
+  imce.syncScroll('#navigation-wrapper', '#navigation-header');
+}
+};
+
+//initiate
+$(document).ready(imce.initiate).ajaxError(imce.ajaxError);
+
 })(jQuery);
\ No newline at end of file
