<?php
/* $id$ */

/**
 * @file
 * GMap Location module is a module to add some gmap funcationality based on location.modules information.
 *
 * The main functions are to provide a map showing all of the nodes or users that have location information on a map.
 *
 */

/**
 * Implementation of hook_help.
 *
 */

function gmap_location_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      return t('Display location.module information on Google Maps (needs gmap.module)');
  }
}

/**
 * Implementation of hook_perm.
 *
 */

function gmap_location_perm() {
  return array('show user map', 'user locations', 'show node map');
}

/**
 * Implementation of hook_menu.
 *
 */

function gmap_location_menu($may_cache) {
  $items=array();

  if ($may_cache) {
    $items[] = array(
      'path' => 'map/user',
        'type' => MENU_NORMAL_ITEM,
      'title' => t('user locations'),
        'access' => user_access('show user map'),
      'callback' => 'gmap_location_user_page'
    );
      $items[] = array('path' => 'map/node',
        'type' => MENU_NORMAL_ITEM,
      'title' => t('node locations'),
        'access' => user_access('show node map'),
      'callback' => 'gmap_location_node_page'
    );
  }

  return $items;
}

/**
 * Draws a page with a google map that has all of the site users.
 *
 */

function gmap_location_user_page() {
  global $user;
  $locationbyuser=array();

  $output ='<p>'.variable_get('gmap_user_map_header', t('This map illustrates the extent of users of this website. Each marker indicates a user that has entered their locations.'))."</p>\n";

  // Find default marker
  $default_marker = variable_get('gmap_user_map_marker', 'drupal');

  // Determine if any roles override default setting
  $roles = user_roles(TRUE);
  $roles_override = array();
  foreach ($roles as $rid => $role) {
    if (variable_get("gmap_role_map_marker_$rid", $default_marker) != $default_marker) {
      $roles_override[$rid] = $role;
    }
  }

  $thismap = gmap_parse_macro(variable_get('gmap_user_map', '[gmap|id=usermap|center=30,0|zoom=2|width=100%|height=400px]'));
  if (empty($thismap['markers'])) {
    $thismap['markers']=array();
  }
  $result=db_query("SELECT * FROM {location} WHERE (longitude !=0 OR latitude !=0) AND type='user'");

  while ($u=db_fetch_object($result)) {
    $account = user_load(array('uid' => $u->oid));
    $dupes = array_intersect($account->roles, $roles_override);
    if (empty($dupes)) {
      $marker = $default_marker;
    }
    else {
      $key = key($dupes);
      $marker = variable_get("gmap_role_map_marker_$key", $default_marker);
    }
    if (user_access('user locations')) {
      $newmarker['label'] = theme('gmap_location_user_html',$account);
      $newmarker['point']= $u->latitude.','.$u->longitude;
      $newmarker['markername']=$marker;
      $newmarker['tooltip']=check_plain($account->name);
      $locationbyuser[$u->oid] = $u->latitude.','.$u->longitude;
    }
    else {
      $newmarker['point']= $u->latitude.', '.$u->longitude;
      $newmarker['markername']=$marker;
    }
    $thismap['markers'][]=$newmarker;
  }
  
  if (user_access('user locations') && function_exists('buddylist_get_buddies') && count($locationbyuser)>0) {
    //create lines for buddies
    if (!isset($thismap['shapes'])) {
      $thismap['shapes']=array();
    }
    ksort($locationbyuser);
    foreach ($locationbyuser as $key=>$value) {
      $buddies= buddylist_get_buddies($key);
      foreach ($buddies as $bkey=>$bvalue) {
        if ($bkey > $key && isset($locationbyuser[$bkey])) {
          $thismap['shape'][]= array(
            'points'=>array($locationbyuser[$key],$locationbyuser[$bkey]),
            'type'=>'line'
          );
        }
      }
    }
  }
  
  $output .= '<p>'.gmap_draw_map($thismap);
  if ($user->uid>0) {
    $output .= '<p>'.t('To add/change your location to the user map, ').l(t('edit your location'),'user/'.$user->uid.'/edit/gmap_user');
  }
  return $output;
}

/**
 * Draws a page with a google map with the node on it, or if no node is set all of the nodes on it.
 *
 * @param $nn
 * The node number to draw on the map.  If this is not set, or is null then all of the nodes will be drawn.
 */


function gmap_location_node_page($nid=null) {
  if ($nid && $n=node_load($nid)){
    if (node_access('view',$n)) {
      $output .='<p>'.variable_get('gmap_node_map_header', t('This map illustrates the extent of nodes of this website. '))."</p>\n";
      $thismap = gmap_parse_macro(variable_get('gmap_node_map', '[gmap|id=nodemap|center=30,0|zoom=2|width=100%|height=400px]'));
      $thismap = gmap_location_node_map($n,$thismap,true);
      $output .= '<p>'.gmap_draw_map($thismap);
      return $output;
    }
    else {   //access denied
      return drupal_access_denied();
    }
  }

  $output .='<p>'.variable_get('gmap_node_map_header', t('This map illustrates the extent of nodes of this website.'))."</p>\n";

  $result=db_query("SELECT oid, longitude, latitude FROM {location} WHERE (longitude!=0 OR latitude !=0) AND type='node'");
  $thismap = gmap_parse_macro(variable_get('gmap_node_map', '[gmap|id=usermap|center=30,0|zoom=2|width=100%|height=400px]'));
  if (empty($thismap['markers'])) {
    $thismap['markers']=array();
  }
  while ($locn=db_fetch_object($result)) {
    $n=node_load($locn->oid);
    if ($n && node_access('view',$n)) {
      $thismap=gmap_location_node_map($n,$thismap,false);
    }
  }

  $output .= '<p>'.gmap_draw_map($thismap);
  return $output;
}


/**
 * Adds the location information from a node for a gmap.
 *
 * @param $n
 * The node object to add to the map.
 *
 * @param $thismap
 * A gmap var with the map that will be used as the basemap
 *
 * @param $single
 * true if this is the only node being looked at (will center the map and possible add
 * additional information.
 *
 * @return
 * A gmap centred on the
 */

function gmap_location_node_map($n,$thismap,$single=false){
  if ((isset($n->gmap_location_latitude) && isset($n->gmap_location_longitude)) || (isset($n->location['latitude']) && isset($n->location['longitude']))){
    $latitude = isset($n->gmap_location_latitude) ? $n->gmap_location_latitude : $n->location['latitude'];
    $longitude = isset($n->gmap_location_longitude) ? $n->gmap_location_longitude : $n->location['longitude'];

    $newmarker=array();
    $width=0;

    if (!($newmarker['text'] = theme(strtr($n->type,'-','_').'_gmapnodelabel',$n))) {
      $newmarker['text'] = theme('gmapnodelabel',$n);
    }
    $newmarker['point']= $latitude.','.$longitude;
    $newmarker['markername']=variable_get('gmap_node_marker_'.$n->type, '');
    $newmarker['tooltip']=$n->title;
    $newmarker['link']=url('node/'.$n->nid);
    switch ($n->type) {
      case 'acidfree':
        $newmarker['winwidth'] = (variable_get('acidfree_thumb_dim', IMAGE_THUMB_SIZE)+40).'px';
        break;
    }
    $thismap['markers'][]=$newmarker;
    if ($single){
      $thismap['center']=$latitude.','.$longitude;
    }

  }
  if ($single) {
    //do special things for certain nodes when it is the only node shown
    switch ($n->type) {
      case 'og':
        $result=db_query(og_list_users_sql(), $n->nid);
        while ($user = db_fetch_object($result)) {
          if (isset($user->location['latitude']) && isset($user->location['longitude'])) {
            if (user_access('user locations')) {
              $newmarker=array();
              $newmarker['label'] = theme('user_picture', $user);
              $newmarker['label'] .= theme('username', $user);
              $newmarker['point']= $latitude.','.$longitude;
              $newmarker['markername']=variable_get('gmap_user_map_marker', 'drupal');
              $thismap['markers'][]=$newmarker;
            }
          }
          else {
            $newmarker['point']= $u->latitude.', '.$u->longitude;
            $thismap['markers'][]=$newmarker;
          }
        }
        break;
    }
  }
  return $thismap;
}

/**
 * Implementation of hook_settings.
 *
 */

function gmap_location_settings() {

  $markers=gmap_get_markers();
  
  $form['geocoding'] = array(
    '#type' => 'fieldset',
    '#title' => t('Geocode Locations'),
  );
  $form['geocoding']['gmap_geocode'] = array(
    '#type'=>'radios',
    '#title'=>t('Enable the Google Map API geocoding'),
    '#default_value'=>variable_get('gmap_geocode', 1),
    '#options' => array(1=>'Enabled', 0=>'Disabled'),
  );


  $form['user'] = array(
    '#type' => 'fieldset', 
    '#title' => t('Location settings for users'),
  );
  $form['user']['gmap_user'] = array(
    '#type'=>'checkbox',
    '#title'=>t('Profile map'),
    '#default_value'=>variable_get('gmap_user', true),
    '#description'=>t('Let users set/edit their location in their profile.'),
  );
  $form['user']['gmap_user_profile_category'] = array(
    '#type'=>'textfield',
    '#title'=>t('Profile category title'),
    '#default_value'=>variable_get('gmap_user_profile_category', "Location map"),
    '#size'=>50,
    '#maxlength'=>50,
    '#description'=>t('Let users set/edit their location in their profile.'),
  );
  $form['user']['gmap_user_map'] = array(
    '#type'=>'textfield',
                                       '#title'=>t('Default user map'),
                                       '#default_value'=>variable_get('gmap_user_map', '[gmap |id=usermap|center=40,0|zoom=3|width=100%|height=400px]'),
                                       '#size'=>50,
                                       '#maxlength'=>500,
    '#description'=>t('The gmap macro where the user information will be diplayed on.'),
  );
  $form['user']['gmap_user_map_header'] = array(
    '#type'=>'textarea',
                                              '#title'=>t('Text at the top of the map/users page'),
                                              '#default_value'=>variable_get('gmap_user_map_header', t('This map illustrates the extent of users of this website. Each marker indicates a user that has entered their locations.')),
                                              '#cols'=>50,
    '#rows'=>6 ,
  );
  $form['user']['gmap_user_map_marker'] = array(
    '#type'=>'select',
                                              '#title'=>t('Marker for users'),
                                              '#default_value'=>variable_get('gmap_user_map_marker', 'drupal'),
    '#options'=>$markers,
  );

  // Option to use a different marker for each role
  $form['user']['roles'] = array(
    '#type'=>'fieldset',
                               '#title'=>t('Markers per role'),
    '#description'=>t('Use a different marker to denote users in the following roles.'),
  );

  // Retrieve and sort list of roles, sans anonymous user
  $roles = user_roles(TRUE);
  asort($roles);

  // Create a selection box per role
  foreach ($roles as $rid => $role) {
    $form['user']['roles']["gmap_role_map_marker_$rid"] = array(
      '#type'=>'select',
                                                              '#title'=>$role,
                                                              '#default_value'=>variable_get("gmap_role_map_marker_$rid", variable_get('gmap_user_map_marker', 'drupal')),
      '#options'=>$markers,
    );
  }


  $form['node'] = array(
    '#type' => 'fieldset', 
    '#title' => t('Location settings for nodes'),
  );
  $form['node']['gmap_node_map'] = array(
    '#type'=>'textfield',
                                       '#title'=>t('Default node map'),
    '#default_value'=>variable_get('gmap_node_map', '[gmap |id=nodemap|center=40,0|zoom=3|width=100%|height=400px]'),
                                       '#size'=>50,
                                       '#maxlength'=>500,
    '#description'=>t('The gmap macro where the user information will be diplayed on.'),
  );
  $form['node']['gmap_node_map_header'] = array(
    '#type'=>'textarea',
                                              '#title'=>t('Text at the top of the map/nodes page'),
                                              '#default_value'=>variable_get('gmap_node_map_header', t('This map illustrates the locations of the nodes on this website. Each marker indicates a node associated with a specific location.')),
                                              '#cols'=>50,
    '#rows'=>6 
  );

  $ntypes=node_get_types();
  foreach ($ntypes as $key => $value) {
    if (variable_get('location_'. $key, 0)) {
      $form['node']['gmap_node_marker_'.$key]=array(
        '#type'=>'select',
                                                        '#title'=>t('Marker for '.$value),
        '#default_value'=>variable_get('gmap_node_marker_'.$key, ''),
        '#options'=>$markers,
      );
    }
  }
  return $form;
}

function gmap_location_block($op = 'list', $delta = 0, $edit = array()) {

  // The $op parameter determines what piece of information is being requested.
  switch ($op) {
    case 'list':
      $blocks[0]['info'] = t('Location map');
 //     $blocks[1]['info'] = t('Author map');  More work than I originally thought.  I will get back to this soon...
      return $blocks;
    case 'configure':
      $form = array();
      if ($delta == 0) {
         $form['gmap_location_block_macro'] = array(
          '#type' => 'textfield',
          '#title' => t('Map Macro'),
          '#size' => 60,
          '#maxlength'=>500,
          '#description' => t('A macro to be used as a base map for the location block.  This map will be recentered on the location, so the center is not that important. <p>Alternate base map macros can be entered for a specific node type below.'),
          '#default_value' =>
            variable_get('gmap_location_block_macro', '[gmap |id=block0|zoom=10 |width=100% |height=200px |control=Small |type=Map] '),
        );
        
        $ntypes=node_get_types();
        foreach ($ntypes as $key => $value) {
          if (variable_get('location_'. $key, 0)) {
            $form['gmap_location_block_macro_'.$key]=array(
                                                          '#type' => 'textfield',
                                                          '#title' => t('Map Macro for '.$value),
                                                          '#size' => 60,
                                                          '#maxlength'=>500,
             '#default_value' => variable_get('gmap_location_block_macro_'.$key, ''),
            );
          }
        }
      }
      elseif ($delta == 1) {
         $form['gmap_location_auther_block_macro'] = array(
          '#type' => 'textfield',
          '#title' => t('Map Macro'),
          '#size' => 60,
          '#maxlength'=>500,
          '#description' => t('A macro to be used as a base map for the location block author.  This map will be recentered on the location, so the center is not that important.'),
          '#default_value' =>
            variable_get('gmap_location_author_block_macro', '[gmap |id=block0|zoom=10 |width=100% |height=200px |control=Small |type=Map] '),
        );

        $ntypes=node_get_types();
        foreach ($ntypes as $key => $value) {
          if (variable_get('location_'. $key, 0)) {
            $form['gmap_location_author_block_'.$key]=array(
                              '#type' => 'checkbox',
                              '#title' => t('Authoer block enabled '.$value),
                              '#default_value' => variable_get('gmap_location_author_block_'.$key, 0),
            );
          }
        }
      }
      return $form;
    case 'save':
      if ($delta == 0) {
        // Have Drupal save the string to the database.
        variable_set('gmap_location_author_block_macro', $edit['gmap_location_author_block_macro']);
        $ntypes=node_get_types();
        foreach ($ntypes as $key => $value) {
          if (variable_get('location_'. $key, 0)) {
            variable_set('gmap_location_block_macro_'.$key,$edit['gmap_location_block_macro_'.$key]);
          }
        }
      }
      elseif ($delta == 1) {
        // Have Drupal save the string to the database.
        variable_set('gmap_location_author_block_macro', $edit['gmap_location_author_block_macro']);
        $ntypes=node_get_types();
        foreach ($ntypes as $key => $value) {
          if (variable_get('location_'. $key, 0)) {
            variable_set('gmap_location_author_block_'.$key,$edit['gmap_location_author_block_'.$key]);
          }
        }
      }
      return;

    case 'view': default:

      // If $op is "view", then we need to generate the block for display
      // purposes. The $delta parameter tells us which block is being requested.
      switch ($delta) {
        case 0:
          // The subject is displayed at the top of the block. Note that it
          // should be passed through t() for translation.
          $path = drupal_get_normal_path($_GET['q']);
          list($node, $nid) = array_values(explode('/', $path));
          if ($node == 'node') {
            $block=gmap_location_block_view($nid);
          }
          break;
        case 1:
          // The subject is displayed at the top of the block. Note that it
          // should be passed through t() for translation.
          $path = drupal_get_normal_path($_GET['q']);
          list($node, $nid) = array_values(explode('/', $path));
          if ($node == 'node') {
            $block=gmap_location_author_block_view($nid);
          }
          break;
      }
      return $block;
  }
}

function _gmap_location_getlatlon($node) {
  if (isset($node->gmap_location_latitude) && isset($node->gmap_location_longitude)) {
    return array('latitude'=>$node->gmap_location_latitude, 'longitude'=>$node->gmap_location_longitude);
  }
  elseif (isset( $node->location['latitude']) &&  isset($node->location['longitude'])) {
    return array('latitude'=>$node->location['latitude'], 'longitude'=>$node->location['longitude']);
  }
  else {
    return false;
  }
}

function gmap_location_block_view($nid) {
  $block=array();
  $node = node_load(array('nid' => $nid));
  if (_gmap_location_getlatlon($node)) {
    $block['subject'] = t('Location');
    if (strlen(variable_get('gmap_location_block_macro_'.$node->type, '')) > 0) {
      $macro=variable_get('gmap_location_block_macro_'.$node->type, '');
    }
    else {
      $macro=variable_get('gmap_location_block_macro', '[gmap |id=block0|zoom=10 |width=100% |height=200px |control=Small |type=Map] ');
    }
    $block['content'] = gmap_draw_map(gmap_location_map_add_node( gmap_parse_macro($macro),$node));
  }
  return $block;
}

function gmap_location_author_block_view($nid) {
  $block=array();
/*
  $node = node_load(array('nid' => $nid));
  if (variable_get('gmap_location_author_block_'.$node->type)) {
    $block['subject'] = t('Author Location');
    load_user(array($node->author))
    if (strlen(variable_get('gmap_location_block_macro_'.$node->type, '')) > 0) {
      $macro=variable_get('gmap_location_block_macro_'.$node->type, '');
    }
    else {
      $macro=variable_get('gmap_location_block_macro', '[gmap |id=block0|zoom=10 |width=100% |height=200px |control=Small |type=Map] ');
    }
    $block['content'] = gmap_draw_map(gmap_location_map_add_node( gmap_parse_macro($macro),$node));
  }
*/
  return $block;
}


function gmap_location_map_add_node($basemap, $node, $label='') {
  $location=_gmap_location_getlatlon($node);
  if (empty($basemap['markers'])) {
    $thismap['markers']=array();
  }
  $newmarker['point']= $location['latitude'].','.$location['longitude'];
  $newmarker['markername']=variable_get('gmap_node_marker_'.$node->type, '');
  $newmarker['label']=$label;
  $basemap['markers'][]=$newmarker;
  $basemap['center']= $location['latitude'].','.$location['longitude'];
  return $basemap;
}


//Any module can create a default theme for the display of nodes of the node type by
//creating a function theme_hook_gmapnodelabel a theme could then further specify it
//by creating a mytheme_nodetype_gmapnodelabel or could simply create a default
//node type by creating a mytheme_gmapnodelabel

function theme_acidfree_gmapnodelabel($n) {
  $out = strtr(theme_acidfree_print_thumb_photo($n),"'\n",'" ');                   //<table><tr><td> </td></tr></table>
  $width=120;
  return $out;
}
function theme_image_gmapnodelabel($n) {
  $out = '<a href="'.url('node/'.$n->nid).'">'.check_plain($n->title).'</a> <br>';
  $out .= image_display($n,'thumbnail');
  return $out;
}
function theme_gmapnodelabel($n) {
          // Allow a module (where the module name matches the node type name)
          // to define a custom display for the google map label.
          // For this to work with flexinode defined data types,
          // a module called 'flexinode_#.module' in your site's module
          // directory and add theme_hook_gmapnodelabel($node, $location) to it.
          // Be sure to enable your 'flexinode_#.module'.
  return strtr(theme('node',$n,true),"'\n\r",'"  ');    //make sure it all goes on one line.
}

function theme_gmap_location_user_html($account) {
  $returntxt = theme('user_picture', $account);
  $returntxt .= theme('username', $account);
  return $returntxt;
}

function gmap_location_user($op, &$edit, &$user, $category = NULL) {
  if (module_exist('gmap') && variable_get('gmap_user', 0)) {
    $object->gmap_location_latitude = $edit['gmap_location_latitude'];
    $object->gmap_location_longitude = $edit['gmap_location_longitude'];
    $object->oid = $user->uid;

    switch ($op) {
      case 'categories':
        return array(array('name'=>'gmap_user', 'title'=> variable_get('gmap_user_profile_category', t('location map')),'weight'=>5));
      case 'validate':
        _gmap_location_validate_form($object);
        return;
      case 'load':
        $res=db_query("SELECT * FROM {location} WHERE oid=%d AND type='user'",$user->uid);
        if ($gmap_user=db_fetch_array($res)) {
          if ($gmap_user['latitude'] !=0) $user->gmap_location_latitude=  $gmap_user['latitude'];
          if ($gmap_user['longitude']!=0) $user->gmap_location_longitude= $gmap_user['longitude'];
          $user->gmap_location_set=true;
        }
        return;
      case 'insert':
        _gmap_location_store_location($object, 'user', false);
        return;

      case 'update':
        _gmap_location_store_location($object, 'user', isset($user->gmap_location_set));
        return;

      case 'delete':
        db_query ("DELETE from {location} WHERE oid=%d AND type='user'", $user->uid);
        return;

      case 'form':
        if($category == 'gmap_user') _gmap_location_map_form($form, $edit, 'user');

        return  $form;
    }
  }
}


function gmap_location_form_alter($form_id, &$form) {
  $type = $form['type']['#value'];
  $node = $form['#node'];

  if (module_exist('location')) {
    return;
  }

  switch ($form_id) {
    case $type .'_node_settings':
      $markers=gmap_get_markers();

      $form['gmap'] = array(
        '#type' => 'fieldset',
        '#title' => t('Google Maps'),
        '#weight' => 0);             //0 puts at the top, 1 puts it at the bottom below the submit??
      $form['gmap']['gmap_node_'. $type] = array(
        '#type' => 'checkbox',
        '#title' => t('Allow users to add Google Maps info to this node type'),
        '#default_value' => variable_get('gmap_node_'. $type, 0),
        '#description' => t('The location information will be available to the google maps module, and can be shown in a block.'),
        '#required' => FALSE,
      );
      $form['gmap']['gmap_node_marker_'.$type] = array(
        '#type'=>'select',
        '#title'=>t('Marker for this nodetype'),
        '#default_value'=>variable_get('gmap_node_marker_'.$type, variable_get('gmap_user_map_marker', 'drupal')),
        '#options'=>$markers,
      );
      break;
    case $type .'_node_form':
      if(variable_get('gmap_node_'. $type, 0)) {
        $edit = array();
        _gmap_location_map_form($form, $edit, 'node');
      }
      break;
  }
}

/**
 *  implementation of hook_form()
 */

function gmap_location_form(&$node, &$param) {

}

function gmap_location_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  if(variable_get('gmap_node_'. $node->type, 0)) {
    $object->gmap_location_latitude = $node->gmap_location_latitude;
    $object->gmap_location_longitude = $node->gmap_location_longitude;
    $object->oid = $node->nid;

    switch ($op) {
      case 'load':
        $res=db_query("SELECT * FROM {location} WHERE oid=%d AND type='node'",$node->nid);
        if ($gmap_node=db_fetch_array($res)) {
          if ($gmap_node['latitude'] !=0) $node->gmap_location_latitude= $gmap_node['latitude'];
          if ($gmap_node['longitude']!=0) $node->gmap_location_longitude=$gmap_node['longitude'];
          $node->gmap_location_set=true;
        }
        return;

      case 'validate':
        _gmap_location_validate_form($object);
        return;

      case 'insert':
        _gmap_location_store_location($object, 'node', false);
        return;

      case 'update':
        _gmap_location_store_location($object, 'node', isset($node->gmap_location_set));
        return;

      case 'delete':
        db_query ("DELETE from {location} WHERE oid=%d AND type='node'", $node->nid);
        return;

    }
  }
}

function _gmap_location_map_form(&$form, &$edit, $type) {
  if($type=="user") {
    $latitude = $edit['gmap_location_latitude'];
    $longitude = $edit['gmap_location_longitude'];
  }
  else {
    $latitude = $form['#node']->gmap_location_latitude;
    $longitude = $form['#node']->gmap_location_longitude;
  }

  $form['coordinates']=array(
    '#type' => 'fieldset',
    '#title' => t('Coordinates'),
    '#weight' => 5,
    '#collapsible' => $type!='user', 
    '#collapsed' => false,
  );
  $form['coordinates']['gmap_node']=array(
    '#type'=>'markup',
    '#value'=>'');
  $form['coordinates']['gmap_location_latitude']=array(
    '#type'=>'textfield',
    '#id'=>'gmap-latitude',
    '#title'=>t('Latitude'),
    '#default_value'=>$latitude,
    '#size'=>30,
    '#maxlength'=>120,
    '#attributes'=>array('onchange'=>'gmap_textchange();'),
  );
  $form['coordinates']['gmap_location_longitude']=array(
    '#type'=>'textfield',
    '#title'=>t('Longitude'),
    '#default_value'=>$longitude,
    '#size'=>30,
    '#maxlength'=>120,
    '#description'=>t('The latitude and longitude will be entered here when you click on a location in the interactive map below. You can also fill in the values manually.'),
    '#attributes'=>array('onchange'=>'gmap_textchange();'),
  );
  $fields=array('longitude'=>'gmap_location_longitude',
                             'latitude'=>'gmap_location_latitude',);
  if (variable_get('gmap_geocode', 1)) {
     $form['coordinates']['gmap_location_address']=array(
      '#type'=>'textfield',
      '#title'=>t('Address'),
      '#default_value'=>'',
      '#size'=>30,
      '#maxlength'=>120,
      '#id'=>'gmap-address',
      '#description'=>t('The address to be found on the map.  Enter an address and then hit "TAB" and the current location will be updated.  Please note that this address is not saved for the node, it is only used for finding a location.'),

     );
     $fields['address']='gmap_location_address';
  }
  $form['coordinates']['gmap_node']['#value']= gmap_set_location(
       variable_get('gmap_'.$type.'_map', '[gmap|id='.$type.'map|center=0,30|control=Large|type=Hybrid|zoom=16|width=100%|height=400px]'),
       $form['coordinates'],$fields);
}

function _gmap_location_validate_form(&$object) {
  if (isset($object->latitude)){
    if (!is_numeric($object->latitude) || abs($object->latitude)>90) {
      form_set_error('gmap_location_latitude', t('Latitude must be between -90 and 90'));
    }
  }
  if (isset($object->longitude)){
    if (!is_numeric($object->longitude) || abs($object->longitude)>180) {
      form_set_error('gmap_location_longitude', t('Longitude must be between -180 and 180'));
    }
  }
}

function _gmap_location_store_location(&$object, $type, $update = false) {
  if (isset($object->gmap_location_latitude) && isset($object->gmap_location_longitude)) {
    if ($update) {
      db_query("UPDATE {location} SET latitude='%f', longitude='%f', source='%d' WHERE oid='%d' AND type='%s'",  
      $object->gmap_location_latitude,$object->gmap_location_longitude, 1,$object->oid, $type);

    }
    else {
      // based on location.module LOCATION_LATLON_USER_SUBMITTED=1
      db_query("INSERT INTO {location} (oid, type, latitude, longitude, source) VALUES (%d, '%s', '%f', '%f', '%d')", 
      $object->oid, $type, $object->gmap_location_latitude,$object->gmap_location_longitude, 1); 
          }
    unset($object->gmap_location_latitude);
    unset($object->gmap_location_longitude);
    unset($object->gmap_location_set);
  }
}
