<?php
/**
 *  Implementation of hook_requirements - ensure that the documentViewer library is installed
 */
function document_cloud_requirements($phase) {
  if ($phase == 'runtime') {
    $requirements = array();
    $lib_path = libraries_get_path('documentViewer');
    $path =  $lib_path . '/document-viewer/public/assets/viewer.js';
    if (!file_exists($path)) {
         $url = l('github', 'http://github.com/documentcloud/document-viewer/zipball/frontend');
         $requirements['document_cloud'] = array(
          'title' => t('Document Cloud'),
          'value' => t('Required Library "DocumentViewer" is not installed. Download the library from !url, unzip it and place (all) the contents in %path.', 
                        array('!url' => $url,'%path' => $lib_path.'/')),
          'severity' => REQUIREMENT_ERROR
          );
    }
    return $requirements; 
  }
}


/**
 * Implementation of hook_field_info().
 */
function document_cloud_field_info() {
  return array(
    'document_cloud_doc' => array(
      'label' => t('DocumentCloud Document'),
      'description' => t('Store information to link to a document residing on DocumentCloud.')
    ),
  );
}

/**
 * Implementation of hook_field_settings().
 */
function document_cloud_field_settings($op, $field) {
  switch ($op) {
    case 'form':
      $form = array();

      $form['viewer_height'] = array(
        '#type' => 'textfield',
        '#title' => t('DocumentViewer Height'),
        '#default_value' => $field['viewer_height'] ? ((int) $field['viewer_height']).'' : '600',
        '#description' => t('Define the DocumentViewer height in pixels or percentage.'),
      );
      $form['viewer_width'] = array(
        '#type' => 'textfield',
        '#title' => t('DocumentViewer Width'),
        '#default_value' => $field['viewer_width'] ? ((int) $field['viewer_width']).'' : '980',
        '#description' => t('Define the DocumentViewer width in pixels or precentage.'),
      );
    
      return $form;
    
    case 'sanitize':
      
      break;
    case 'validate':
   
      break;
    case 'save':
      return array('viewer_height', 'viewer_width');

    case 'database columns':
      $columns = array();
      $columns['doc_id'] = array(
        'type' => 'varchar', 
        'length' => is_numeric($field['max_length']) ? $field['max_length'] : 255, 
        'not null' => FALSE, 
        'sortable' => TRUE, 
        'views' => TRUE,
      );
      $columns['url'] = array(
        'type' => 'varchar', 
        'length' => is_numeric($field['max_length']) ? $field['max_length'] : 255, 
        'not null' => FALSE, 
        'sortable' => TRUE, 
        'views' => TRUE,
      );
      $columns['title'] = array(
        'type' => 'varchar', 
        'length' => is_numeric($field['max_length']) ? $field['max_length'] : 255, 
        'not null' => FALSE, 
        'sortable' => TRUE, 
        'views' => TRUE,
      );
      $columns['description'] = array(
        'type' => 'text', 
        'not null' => FALSE, 
        'sortable' => TRUE, 
        'views' => TRUE,
      );
      $columns['thumb'] = array(
        'type' => 'varchar', 
        'length' => is_numeric($field['max_length']) ? $field['max_length'] : 255, 
        'not null' => FALSE, 
        'sortable' => TRUE, 
        'views' => TRUE,
      );
      return $columns;

   case 'views data':
      $data = content_views_field_views_data($field);
      // Make changes to $data as needed here.
      return $data;
  }
}

/**
 * Implementation of hook_content_is_empty().
 */
function document_cloud_content_is_empty($item, $field) {
    return empty($item['url']);
}

/**
 * Implementation of hook_field().
 */
function document_cloud_field($op, &$node, $field, &$items, $teaser, $page) {
  switch ($op) {
    case 'validate' :
        foreach ($items as $delta => $value) {
          _document_cloud_validate($items[$delta], $delta, $field, $node);
        }

      return $items;
    
    case 'load' :
      //add some settings to the node object so we can properly style the viewer - 37 = %
     if(!stristr($field['viewer_height'], 37) && !stristr($field['viewer_height'], 'px')){
        $height = $field['viewer_height'] . 'px';
      } else {
        $height = $field['viewer_height'];
      }
      
      if(!stristr($field['viewer_width'], 37) && !stristr($field['viewer_width'], 'px')){
        $width = $field['viewer_width'] . 'px';
      } else {
        $width = $field['viewer_width'];
      }
      
      //add the cached data back to the object if it exists - otherwise recache it and load it on then.
      foreach($items as $key=>$item) {
        $id = document_cloud_get_id($item['url']);
        if($id){
          $cached_data = cache_get('documentcloud:'.$id);
          $cached_data = $cached_data ? $cached_data->data : FALSE;
          
          if($cached_data){
            $items[$key]['doc_id'] = $id;
            $items[$key]['description'] = $cached_data['description'];
            $items[$key]['thumb'] = $cached_data['thumb'];
            $items[$key]['title'] = $cached_data['title'];
          } else {
            $doc = document_cloud_get_from_cloud($id);
            $image = $doc->document->resources->page->image;
            $image = str_replace('{page}', '1', $image);
            $image = str_replace('{size}', 'normal', $image);
            $doc_data = array(
              'title' => $doc->document->title, 
              'thumb' => $image,
              'description' => $doc->document->description,
            );
            cache_set('documentcloud:'.$id, $doc_data);
            $items[$key]['title'] = document_cloud_trim_title($doc->document->title);
            $items[$key]['doc_id'] = $id;
            $items[$key]['description'] = $doc->document->description;
            $image = $doc->document->resources->page->image;
            $image = str_replace('{page}', '1', $image);
            $image = str_replace('{size}', 'normal', $image);
            $items[$key]['thumb'] = $image;
          }
        }
      }
      //print '<pre>'; print_r($items); print '</pre>'; die();  
      return array('viewer_height' => $height, 'viewer_width' => $width);
      break;
    case 'sanitize':
      foreach ($items as $delta => $item) {
        _document_cloud_sanitize($items[$delta], $delta, $field, $node);
      }
      break;
    
    case 'presave':
      foreach ($items as $delta => $item) {
        if($item['url']){
          $doc = document_cloud_get_from_cloud(document_cloud_get_id($item['url']));
          $items[$delta]['id'] = $doc->document->id;
          $image = $doc->document->resources->page->image;
          $image = str_replace('{page}', '1', $image);
          $image = str_replace('{size}', 'normal', $image);
          $doc_data = array(
            'title' => $doc->document->title, 
            'thumb' => $image,
            'description' => $doc->document->description,
          );
          cache_set('documentcloud:'.$doc->document->id, $doc_data);
        } else {
          $items[$delta]['url'] = '';
        }
      }
      break;
  }
}

function _document_cloud_sanitize(&$item, $delta, &$field, &$node) {
  // Don't try to process empty links.
  if (empty($item['url'])) {
    return;
  }
  
  // Replace URL tokens.
  if (module_exists('token') && $field['enable_tokens']) {
    // Load the node if necessary for nodes in views.
    $token_node = isset($node->nid) ? node_load($node->nid) : $node;
    $item['url'] = token_replace($item['url'], 'node', $token_node);
  }

  $url = check_url($item['url']);

  // Separate out the anchor if any.
  if (strpos($url, '#') !== FALSE) {
    $item['fragment'] = substr($url, strpos($url, '#') + 1);
    $url = substr($url, 0, strpos($url, '#'));
  }
  // Separate out the query string if any.
  if (strpos($url, '?') !== FALSE) {
    $item['query'] = substr($url, strpos($url, '?') + 1);
    $url = substr($url, 0, strpos($url, '?'));
  }
 
  $item['url'] = $url;
}


function _document_cloud_validate(&$item, $delta, $field, $node) {
  if(!$item || empty($item)){
    form_set_error($field['field_name'] .']['. $delta .'][url', t('Not a valid URL.'));
  }
  if ($item['url'] && !(isset($field['widget']['default_value'][$delta]['url']) && 
        $item['url'] == $field['widget']['default_value'][$delta]['url'] && !$field['required'])) {
    if(!($id = document_cloud_get_id($item['url']))){
      form_set_error($field['field_name'] .']['. $delta .'][url', t('Not a valid DocumentCloud URL.'));
    } 
    
  }
}



/**
 * Implementation of hook_widget().
 */
function document_cloud_widget(&$form, &$form_state, $field, $items, $delta = 0) {
  $element = array();
  $element['url'] = array(
    '#title' => t('DocumentCloud URL'),
    '#description' => t('A link to a DocumentCloud document'),
    '#type' => 'textfield',
    '#default_value' => isset($items[$delta]['url']) ? $items[$delta]['url'] : NULL,
    '#size' => !empty($field['widget']['size']) ? $field['widget']['size'] : 60,
    '#attributes' => array('class' => 'document_cloud'),
    '#maxlength' => !empty($field['columns']['url']['length']) ? $field['columns']['title']['length'] : NULL,
  );
  
  // Used so that hook_field('validate') knows where to 
  // flag an error in deeply nested forms.
  if (empty($form['#parents'])) {
    $form['#parents'] = array();
  }
  $element['_error_element'] = array(
    '#type' => 'value',
    '#value' => implode('][', array_merge($form['#parents'], array('value'))),
  );
  
  return $element;
}

/**
 * Implementation of hook_widget_info().
 */
function document_cloud_widget_info() {
  return array(
    'document_cloud_doc' => array(
      'label' => 'DocumentCloud Document',
      'field types' => array('document_cloud_doc'),
      'description' => t('Store information to link to a document residing on Document Cloud.'),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
  );
}


/**
 * Implementation of hook_field_formatter_info().
 */
function document_cloud_field_formatter_info() {
  return array(
    'default' => array(
      'label' => t('Title and thumbnail as link (default)'),
      'field types' => array('document_cloud_doc'),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
    'just_title' => array(
      'label' => t('Title as link'),
      'field types' => array('document_cloud_doc'),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
  );
}

/**
 * Implementation of hook_theme().
 */
function document_cloud_theme() {
  return array(
    'document_cloud_field_settings' => array(
      'arguments' => array('element' => NULL),
    ),
    'document_cloud_formatter_default' => array(
      'template' => 'theme/document-cloud-list-item',
      'arguments' => array('element' => NULL),
    ),
    'document_cloud_formatter_just_title' => array(
      'arguments' => array('element' => NULL),
    ),
    'document_cloud_document' => array(
      'template' => 'theme/document-cloud-document',
      'arguments' => array('doc' => NULL, 'path' => NULL),
    )
  );
}

function document_cloud_preprocess_document_cloud_formatter_default(&$vars) {
  
  //add some styles
  drupal_add_css(drupal_get_path('module', 'document_cloud') . '/css/document_cloud.css');

  $element = $vars['element'];
  $vars['id'] = document_cloud_get_id($element['#item']['url']);
  $node = $element['#node'];
  $height = $node->viewer_height ? $node->viewer_height : '';
  $width =  $node->viewer_width ? $node->viewer_width : '';
  $options = array('height' => $height, 'width' => $width);
 
  $vars['link'] = $element['#item']['url'] ? document_cloud_get_my_url($element['#item']['url']).$hAndW : $element['#item']['url'];
 
  if(!$element['#item']['title']){
    $cached_data = cache_get('documentcloud:'.$vars['id']);
    $info = $cached_data ? $cached_data->data : FALSE ;
    if($info) {
      $vars['thumbnail'] = $info['thumb'];
      $vars['title'] = $info['title'];
      $vars['description'] = $info['description'];
    }
  } else {
    $vars['thumbnail'] = $element['#item']['thumb'];
    $vars['title'] = $element['#item']['title'];
    $vars['description'] = $element['#item']['description'];;
  }
}

function theme_document_cloud_formatter_just_title(&$vars) {
  $element = $vars;

  $node = $element['#node'];
  $height = $node->viewer_height ? $node->viewer_height : '';
  $width =  $node->viewer_width ? $node->viewer_width : '';
  $hAndW = '/'.$height.'/'.$width;
 
  $vars['link'] = document_cloud_get_my_url($element['#item']['url']).$hAndW;
  $vars['title'] = $element['#item']['title'];
  
  if(!$element['#item']['title']){
    $id = document_cloud_get_id($element['#item']['url']);
    $cached_data = cache_get('documentcloud:'.$id);
    $info = $cached_data ? FALSE : $cached_data->data;
    
    if($info) {
      $vars['title'] = $info['title'];
    }
  } else {
    $vars['title'] = $element['#item']['title'];
  }
  return l($vars['title'], $vars['link']);
}

function document_cloud_preprocess_document_cloud_document(&$vars)
{
  $doc = $vars['doc'];
  $vars['title'] = document_cloud_trim_title($doc->document->title);
  $vars['description'] = $doc->document->description;
  
}

function document_cloud_perm(){
  return array('view documentcloud documents');
}

/**
 *  Implementation of hook_menu
 */
function document_cloud_menu(){
  $items = array();

  $items['admin/settings/document_cloud'] = array(
    'title' => t('DocumentCloud Settings'),
    'description' => t('Configure the DocumentCloud settings for your site'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array('document_cloud_admin_settings'),
    'access arguments' => array('administer site configuration'),
    'type' => MENU_NORMAL_ITEM
   );
  
  $path = variable_get('documentcloud_menu_path', 'documents');
  $items[$path] = array(
    'page callback' => '_document_cloud_view',
    'page arguments' => array(1),
    'access arguments' => array('view documentcloud documents'),
    'type' => MENU_CALLBACK    
  );
  return $items;
}

/**
 *  Implementation of hook_admin_settings();
 */
function document_cloud_admin_settings() {
  $form = array();
  $form['documentcloud_menu_path'] = array(
     '#type' => 'textfield',
     '#title' => t('Menu Path'),
     '#description' => t('The menu path / relative url that document_cloud will use to display documents on your site'),
     '#default_value' => variable_get('documentcloud_menu_path', 'documents')
  );
 
  $form = system_settings_form($form);
  $form['#submit'][] = '_document_cloud_settings_submit';
  return $form;
}

function _document_cloud_settings_submit($form=null) {
  cache_clear_all('*', 'cache_menu', TRUE);
  menu_rebuild();
  drupal_set_message('Menus Successfully Rebuilt');
}

function _document_cloud_view($id=null){

  $path = libraries_get_path('documentViewer');
  $module_path = drupal_get_path('module', 'document_cloud');
  
  if($id) {
    $height = $_GET['height'];
    $width = $_GET['width'];
    $js_settings = array ('document_cloud' => array(
        'height' => $height,
        'width' => $width,
        'id' => $id
      )
    );
    
    drupal_add_js($js_settings, 'setting');
    
    //add IE6 specific css sheets
    drupal_set_html_head('
    <!--[if (!IE)|(gte IE 8)]><!--> 
     <link href="'.url($path).'/document-viewer/public/assets/viewer-datauri.css" media="screen" rel="stylesheet" type="text/css" /> 
     <link href="'.url($path).'/document-viewer/public/assets/plain-datauri.css" media="screen" rel="stylesheet" type="text/css" /> 
    <!--<![endif]--> 
    <!--[if lte IE 7]>
     <link href="'.url($path).'/document-viewer/public/assets/viewer.css" media="screen" rel="stylesheet" type="text/css" />
     <link href="'.url($path).'/document-viewer/public/assets/plain.css" media="screen" rel="stylesheet" type="text/css" />
    <![endif]--> ');
    //drupal_add_js($module_path.'/document-viewer/public/assets/sizzle.js');
    //jquery_ui_add(array('ui.core'));
    drupal_add_js($path.'/document-viewer/public/assets/viewer.js');
    drupal_add_js($path.'/document-viewer/public/assets/templates.js');
    drupal_add_js($module_path.'/js/document_cloud.js');
    
    $doc = document_cloud_get_from_cloud($id);
        
    return theme('document_cloud_document', $doc);
  }
  else {
    drupal_set_message("No document ID was specified.", 'error');
    return "";
  }
}

/**
 *  Get the link to view the document on your site
 */
function document_cloud_get_my_url($docCloudURL, $ops=array()){
  //Need to define some sort of menu hook and make a call back for this function
  global $base_url;
  $match = document_cloud_get_id($docCloudURL);
  $options = array('query' => array('redirect'=>$base_url.request_uri()), 'absolute' => TRUE);
  $options['query'] = array_merge($options['query'], $ops);
  if($match){
    $base = variable_get('documentcloud_menu_path', 'documents');
    return url($base.'/'.$match, $options);
  } 
  else {
    return $docCloudURL;
  }
}

function document_cloud_get_id($url){
  //Need to define some sort of menu hook and make a call back for this function
  
  $regex = '#^((http|https):\/\/)?www\.documentcloud\.org\/documents\/(.+)\.(html|js)#i';
   $matches = array();
   preg_match($regex, $url, $matches);
  if($matches[3])
    return $matches[3];
  else
    return "";
}

function document_cloud_trim_title($title)
{
  if(strlen($title) > 255)
  {
    return substr($title, 0, 252).'...';
  } 
  
  return $title;
}



//---------------------- Functions for dealing with the document_cloud api -------------------------//

function do_request($url, $content="", $type="POST", $content_type="multipart/form-data"){
  $params = array('http' => array(
              'method' => $type,
              'header'=> $type=='POST' ? 'Content-Type: $content_type\r\n' : '',
              'content' => $content
            ));
  $ctx = stream_context_create($params);
  $fp = @fopen($url, 'rb', false, $ctx);
  if (!$fp) {
    throw new Exception("Problem with $url, $php_errormsg");
  }
  $response = @stream_get_contents($fp);
  if ($response === false) {
    throw new Exception("Problem reading data from $url, $php_errormsg");
  }
  return $response;
}

function document_cloud_upload_to_cloud($user, $pass, $file_string, $title, $source, $description, $access){
  if(empty($source)) { $source = 'Demo Document'; }
  
  //create an object to serialize and send to the document_cloud servers
  $url = 'https://'.$user.':'.$pass.'@www.documentcloud.org/api/upload.json';
        
  $data = array(
    'file' => $file_string,
    'title' => $title,
    'source' => $source,
    'description' => $description,
    'access' => $access
  );
    
  return do_request($url, $data);
}

function document_cloud_get_from_cloud($id){
  if(!$id){ return false; }
  $url = 'https://www.documentcloud.org/api/documents/'.$id.'.json';
  return json_decode(do_request($url, "", "GET"));
}

function document_cloud_update_info($id, $title, $source, $description, $related_article, $access){
  $data = array(
    'title' => $title,
    'source' => $source,
    'description' => $description,
    'related_article' => $related_article,
    'access' => $access
  );
  
  $url = 'https://www.documentcloud.org/api/documents/'.$id.'.json';
  
  return json_decode(do_request($url, $data, 'PUT'));
}

function document_cloud_get_list($user, $pass){
  $url = 'https://'.$user.':'.$pass.'@www.documentcloud.org/api/upload.json';
  
  return json_decode(do_request($url, "", "GET")); 
}

//----------------------- End API Functions -----------------------//



?>