<?php

/**
 * Implementation of hook_field_info().
 */
function cck_gmapaddress_field_info() {
  return array(
    'cck_gmapaddress' => array('label' => t('Google Map Address')),
  );
}

/**
 * Implementation of cck hook_field_settings
 */
function cck_gmapaddress_field_settings($op, $field) {
  switch ($op) {
    case 'form':
      $form = array();
	  $form['tld'] = array(
	        '#type' => 'textfield',
	        '#title' => t('Top Level Domain'),
	        '#description' => t("The Domain of the Google Map to use for validation."),
	        '#default_value' => ($field['tld'])?$field['tld']:'com',
		  );
	  $form['accuracy'] = array(
	        '#type' => 'select',
	        '#title' => t('Minimum Accuracy'),
	        '#description' => t("The accuracy of gmap validation."),
	        '#default_value' => $widget['accuracy'],
			'#options'=> _cck_gmapaddress_accuracy(),
		);
	  //GMAP SIMPLE
	  $form['gmap_simple'] = array(	'#type'=>'fieldset',
									'#title'=>t('GMap - Single'),
									'#tree'=>TRUE,
									'#collapsible'=>TRUE,
									'#collapsed'=>TRUE,
									'#description'=> '',
									);
	  $form['gmap_simple']['width'] = array(	'#type'=> 'textfield',
											'#title' => t('Width'),
											'#default_value' =>$field['gmap_simple']['width'],
											'#description' => '"" = default gmap setting, prepend v=,t=, f= or b= with  for views,teaser, full or block view settings, separate with ; <br/> example "600;v=200;t=300"',
											);
	  $form['gmap_simple']['height'] = array(	'#type'=> 'textfield',
											'#title' => t('Height'),
											'#default_value' =>$field['gmap_simple']['height'],
											'#description' => '"" = default gmap setting, prepend v=,t=, f= or b= with  for views,teaser, full or block view settings, separate with ; <br/> example "600;v=200;t=300"',
											);
	  $form['gmap_simple']['zoom'] = array(	'#type'=> 'textfield',
											'#title' => t('Zoom'),
											'#default_value' =>$field['gmap_simple']['zoom'],
											'#description' => '"" = default gmap setting, "auto" = Autozoom, integer (1,2,3...) for custom zoom',
											);
	  $form['gmap_simple']['mtc'] = array(	'#type'=> 'textfield',
											'#title' => t('Map Type Control'),
											'#default_value' =>$field['gmap_simple']['mtc'],
											'#description' => '"" = default gmap setting, "0" = none, "1" = Standard, "2" = Hierarchical, "3" = Dropdown <br/> contains view-control like width',//none,standard,hier,menu
											);
	  $form['gmap_simple']['address'] = array(	'#type'=> 'textfield',
											'#title' => t('Show address'),
											'#default_value' =>$field['gmap_simple']['address'],
											'#description' => '1 for show address, prepend v=,t= or f= with  for views,teaser or full view settings, separate with ; <br/> example "1;v=0;t=0',
											);
	  $form['gmap_simple']['routelink'] = array('#type'=> 'select',
											'#title' => t('Link to route'),
											'#multiple'=>TRUE,
											'#required'=>FALSE,
											'#default_value' => $field['gmap_simple']['routelink'],
											'#options'=>array('full'=>t('Full'),'teaser'=>t('Teaser'),'views'=>t('Views'),'block'=>t('Block')),
											);
	  
	  //GMAP ALL
	  $form['gmap_all'] = array(	'#type'=>'fieldset',
									'#title'=>t('GMap - All addresses in one'),
									'#tree'=>TRUE,
									'#collapsible'=>TRUE,
									'#collapsed'=>TRUE,
									'#description'=> '',
									);
	  $form['gmap_all']['width'] = array(	'#type'=> 'textfield',
											'#title' => t('Width'),
											'#default_value' =>$field['gmap_all']['width'],
											);
	  $form['gmap_all']['height'] = array(	'#type'=> 'textfield',
											'#title' => t('Height'),
											'#default_value' =>$field['gmap_all']['height'],
											);
	  $form['gmap_all']['zoom'] = array(	'#type'=> 'textfield',
											'#title' => t('Zoom'),
											'#default_value' =>$field['gmap_all']['zoom'],
											);
	  $form['gmap_all']['mtc'] = array(	'#type'=> 'textfield',
											'#title' => t('Map Type Control'),
											'#default_value' =>$field['gmap_all']['mtc'],
											'#description' => '"" = default gmap setting, 0 = none, 1 = Standard, 2 = Hierarchical, 3 = Dropdown',//none,standard,hier,menu
											);
	  $form['gmap_all']['address'] = array(	'#type'=> 'textfield',
											'#title' => t('Show address'),
											'#default_value' =>$field['gmap_all']['address'],
											);
	  $form['gmap_all']['routelink'] = array('#type'=> 'select',
											'#title' => t('Link to route'),
											'#multiple'=>TRUE,
											'#required'=>FALSE,
											'#default_value' => $field['gmap_all']['routelink'],
											'#options'=>array('full'=>t('Full'),'teaser'=>t('Teaser'),'views'=>t('Views'),'block'=>t('Block')),
											);
	  //ROUTE SINGLE
	  $form['route_single'] = array(	'#type'=>'fieldset',
									'#title'=>t('Route Link - Single'),
									'#tree'=>TRUE,
									'#collapsible'=>TRUE,
									'#collapsed'=>TRUE,
									'#description'=> '',
									);
	  $form['route_single']['text'] = array(	'#type'=> 'textfield',
											'#title' => t('Route text'),
											'#default_value' =>$field['route_single']['text'],
											);
	  $form['route_single']['start'] = array('#type'=> 'select',
											'#title' => t('Start address'),
											'#multiple'=>FALSE,
											'#default_value' =>$field['route_single']['start'],
											'#options'=>_cck_gmapaddress_routestartend(0),
											);
	  $form['route_single']['start_opt'] = array(	'#type'=> 'textfield',
											'#title' => t('Start options'),
											'#default_value' =>$field['route_single']['start_opt'],
											);
	  $form['route_single']['end'] = array('#type'=> 'select',
											'#title' => t('Destination address'),
											'#multiple'=>FALSE,
											'#default_value' =>$field['route_single']['end'],
											'#options'=>_cck_gmapaddress_routestartend(1),
											);
	  $form['route_single']['end_opt'] = array(	'#type'=> 'textfield',
											'#title' => t('Destination options'),
											'#default_value' =>$field['route_single']['end_opt'],
											);
	  //ROUTE ALL
	  $form['route_all'] = array(	'#type'=>'fieldset',
									'#title'=>t('Route Link - All addresses in one'),
									'#tree'=>TRUE,
									'#collapsible'=>TRUE,
									'#collapsed'=>TRUE,
									'#description'=> '',
									);
	  $form['route_all']['text'] = array(	'#type'=> 'textfield',
											'#title' => t('Route text'),
											'#default_value' =>$field['route_all']['text'],
											);
	  $form['route_all']['start'] = array('#type'=> 'select',
											'#title' => t('Start address'),
											'#multiple'=>FALSE,
											'#default_value' =>$field['route_all']['start'],
											'#options'=>_cck_gmapaddress_routestartend(0),
											);
	  $form['route_all']['start_opt'] = array(	'#type'=> 'textfield',
											'#title' => t('Start options'),
											'#default_value' =>$field['route_all']['start_opt'],
											);
	  $form['route_all']['end'] = array('#type'=> 'select',
											'#title' => t('Destination address'),
											'#multiple'=>FALSE,
											'#default_value' =>$field['route_all']['end'],
											'#options'=>_cck_gmapaddress_routestartend(1),
											);
	  $form['route_all']['end_opt'] = array(	'#type'=> 'textfield',
											'#title' => t('Destination options'),
											'#default_value' =>$field['route_all']['end_opt'],
											);
							
      return $form;
    case 'validate':
      break;
    case 'save':
      return array('tld','accuracy','gmap_all','gmap_simple','route_single','route_all');
    case 'database columns':
	  $columns = array();
	  $columns = array(
			'longitude' => array('type' => 'decimal', 'length' => '18,15', 'unsigned' => FALSE, 'not null' => TRUE, 'default' => 0),
			'latitude' => array('type' => 'decimal', 'length' => '18,15', 'unsigned' => FALSE, 'not null' => TRUE, 'default' => 0),
			'accuracy' => array('type' => 'int', 'length' => 1, 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
			'address' => array('type' => 'varchar', 'length' => 255,'not null' => TRUE, 'default' => "''"),
			'delta' => array('type' => 'int', 'length' => 1, 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
		);
	  return $columns;
    case 'filters':
      return array(
        'default' => array(
          'name' => t('Default'),
          'operator' => 'views_handler_operator_gtlt',
        ),
      );
	/**case 'arguments':
      return FALSE;**/
    case 'callbacks':
      return array(
        'view' => CONTENT_CALLBACK_NONE,
      );
  }
}

/**
 * Implementation of cck hook_field
 */
function cck_gmapaddress_field($op, &$node, $field, &$node_field, $teaser, $page) {
  switch ($op) {
    case 'load':
      break;
    case 'view':
      break;
    case 'validate':
	  foreach ($node_field as $key=>$item){
		//Prüfung ob leer??
		//Proofs on valid geo location in gmap
		if (!$item['status']){
			$gc = gmap_geocode($item['address'],$field['tld']);
			$item = array_merge($item,$gc);
		}
		if ($item['status'] == 610){
			form_set_error($field['field_name'].']['.$key.'][address',t('No valid Google Map Key! Set correct key in !link',array('!link'=>l('GMap Admin',base_path().'admin/settings/gmap'))));		
		} elseif ($item['status']!= 200){
			form_set_error($field['field_name'].']['.$key.'][address',t('The address in %field could not be validated as correct address!',array('%field'=>$field['field_name']."[$key]")));
		} elseif($item['accuracy']<$field['accuracy']) {
			form_set_error($field['field_name'].']['.$key.'][address',t('The address in %field does not have satisfying accuracy!',array('%field'=>$field['field_name']."[$key]")));
		}
	  }
      break;
    case 'insert':
    case 'update':
	  
	  foreach ($node_field as $key => $item){
		$node_field[$key]['delta'] = $key;
	  } 
      break;
  }
}

/**
 * Implementation of cck hook_widget_info
 */
function cck_gmapaddress_widget_info() {
  return array(
    'gmapaddress_textfield' => array(
      'label' => t('GMap Address - Text Field'),
      'field types' => array('cck_gmapaddress'),
    ),
  );
}

/**
 * Implementation of cck hook_widget_settings()
 */
function cck_gmapaddress_widget_settings($op, $widget){
	// $ops save,callbacks,validate get $field instead of $widget
	switch ($op) {
		case 'form':
		  $form = array();
		  return $form;
		case 'validate':
		  break;
		case 'callbacks':
		  return array(
			'default value' => CONTENT_CALLBACK_NONE,
		  );
		case 'save':
		  return array();
	}
}

/**
 * hook_widget()
 */
function cck_gmapaddress_widget($op, &$node, $field, &$node_field) {
  switch ($op) {
    case 'prepare form values':
      break;

    case 'form':
      $form = array();
      $form[$field['field_name']] = array('#tree' => TRUE,
										  '#type' => 'fieldset',
										  '#title'=>t($field['widget']['label']),
										  '#description' => t($field['widget']['description']),
										  );
	  $key = -1;
	  foreach ($node_field as $key => $item){
		if ($field['#multiple'] || $key == 0){
			$form[$field['field_name']][$key] = array('#tree' => TRUE);
			$form[$field['field_name']][$key]['address'] = array(
				'#type' => 'textfield',
				'#default_value' => $item['address'],
				'#required' => ($field['required'] && $key == 0),
			);
		}
	  }
	  $key++;
	  for ($i = $key;$i < 1 - $key + (($field['#multiple'])?3:0);$i++){
		$form[$field['field_name']][$i] = array('#tree' => TRUE);
		$form[$field['field_name']][$i]['address'] = array(
				'#type' => 'textfield',
				'#default_value' => $item['address'],
				'#required' => ($field['required'] && $i == 0),
		);
	  }
	  
      return $form;
	  
    case 'process form values':
	  foreach ($node_field as $key => $item){
		if ($item['address']){
			$gc = gmap_geocode($item['address'],$field['tld']);
							$node_field[$key] = array_merge($item,$gc);
			
		} else {
		  unset($node_field[$key]);
		}
	  }
	  $node_field = array_values($node_field);
      break;
  }
}

/**
 * Implemantation of cck hook_field_formatter_info()
 */
function cck_gmapaddress_field_formatter_info() {
  return array(
    'address' => array(
      'label' => t('Address'),
      'field types' => array('cck_gmapaddress'),
    ),
	'longitude' => array(
      'label' => t('Longitude'),
      'field types' => array('cck_gmapaddress'),
    ),
	'latitude' => array(
      'label' => t('Latidude'),
      'field types' => array('cck_gmapaddress'),
    ),
    'lonlat' => array(
      'label' => t('Longitude and Latidude'),
      'field types' => array('cck_gmapaddress'),
    ),
	'accuracy' => array(
      'label' => t('Accuracy'),
      'field types' => array('cck_gmapaddress'),
    ),
	'gmap_simple' => array(
      'label' => t('GMap - Single'),
      'field types' => array('cck_gmapaddress'),
    ),
	'gmap_all' => array(//Only processed by delta = 0
      'label' => t('GMap - All addresses in one'),
      'field types' => array('cck_gmapaddress'),
    ),
	'route_single' => array(//Only processed by delta = 0
      'label' => t('Route Link - Single'),
      'field types' => array('cck_gmapaddress'),
    ),
	'route_all' => array(
      'label' => t('Route Link - All addresses in one'),
      'field types' => array('cck_gmapaddress'),
    ),
	/**'gmap_route' => array(
      'label' => t('GMap Route'),
      'field types' => array('cck_gmapaddress'),
    ),
	'gmap_route_user' => array(  //Options to come: to first, to last, to every place, from user over first and others to last, $user->field mit lonlat or addresse
      'label' => t('GMap User-Route'),
      'field types' => array('cck_gmapaddress'),
    ),	*/
  );
}

/**
 * hook_field_formatter()
 */
function cck_gmapaddress_field_formatter($field, $item, $formatter, $node,$block = FALSE) {
  //get view-type
  if ($block){
	$view = 'block';
  } elseif(isset($node->node_type)){
    $view = 'views';
  } elseif (strlen($node->teaser) > strlen($node->body)){
    $view = 'teaser';
  } else {
    $view = 'full';
  }
  switch ($formatter) {
    case 'address':
      return check_plain($item['address']);

    case 'longitude':
      return check_plain($item['longitude']);
	case 'latitude':
      return check_plain($item['latitude']);
	case 'lonlat':
      return t('lon: %lon - lat: %lat',array('%lon'=>$item['longitude'],'%lat'=>$item['latitude']));
    
	case 'accuracy':
	  return _cck_gmapaddress_accuracy($item['accuracy']);
	case 'gmap_simple':
	  //this view is processed for every delta
	  if ($item['longitude'] && $item['latitude']){
		//Height & Width
		$height = (strlen($field['gmap_simple']['height'])>0)?_cck_gmapaddress_addpx(_cck_gmapaddress_arrhelper($field['gmap_simple']['height'],$view)):'default';
		$width = (strlen($field['gmap_simple']['width'])>0)?_cck_gmapaddress_addpx(_cck_gmapaddress_arrhelper($field['gmap_simple']['width'],$view)):'default';
		
		//Zoom
		$zoom = _cck_gmapaddress_arrhelper($field['gmap_simple']['zoom'],$view);
		$map['behavior']=array('autozoom'=>($zoom == 'auto'));
		
		//Map Type Control
		if (strlen($field['gmap_simple']['mtc'])>0){
			$map['mtc'] = _cck_gmapaddress_mtc(_cck_gmapaddress_arrhelper($field['gmap_simple']['mtc'],$view));
		}
		//Address
		$address = (_cck_gmapaddress_arrhelper($field['gmap_simple']['address'],$view))?cck_gmapaddress_field_formatter($field,$item,'address',$node):'';
		
		//Route Link
		$link='';
		if (in_array($view,$field['gmap_simple']['routelink'])){
		  $link = cck_gmapaddress_field_formatter($field,$item,'route_single',$node);
		}
		
		return $address.gmap_simple_map($item['latitude'], $item['longitude'],'',$item['address'],$zoom,$width,$height, FALSE, $map).$link;
	  }
	case 'gmap_all':
	  //to avoid multiple view fo same map, view is only processed for delta = 0
	  if ($item['longitude'] && $item['latitude'] && $item['delta']==0){
	    if (empty($node->{$field['field_name']})){
			$node = node_load($node->nid);
		}
		//Markers
		$markers = array();
		$mlon = array();
		$mlat = array();
		$addresses = array();
		foreach ($node->{$field['field_name']} as $key=>$el){
			$markers[] = array(	'longitude'=>$el['longitude'],
								'latitude'=>$el['latitude'],
								'text'=>$el['address'],
								'offset'=>$key,
						 );
			$mlon[] = $el['longitude'];
			$mlat[] = $el['latitude'];
			$addresses[] = $el['address'];
		}
		$settings = array('markers'=>$markers);
		//Position
		$settings['longitude'] = (min($mlon)+max($mlon))/2;
		$settings['latitude'] = (min($mlat)+max($mlat))/2;
		//Zoom
		$zoom = _cck_gmapaddress_arrhelper($field['gmap_all']['zoom'],$view);
		if ($zoom=='auto'){
			$settings['behavior'] = array('autozoom' => TRUE);
		} elseif ($zoom > 0 && $zoom < 20) {
			$settings['zoom'] = $zoom;
		}
		//Height & Width
		if (strlen($field['gmap_all']['height'])>0){
			$settings['height'] = _cck_gmapaddress_addpx(_cck_gmapaddress_arrhelper($field['gmap_all']['height'],$view));
		}
		if (strlen($field['gmap_all']['width'])>0){
			$settings['width'] = _cck_gmapaddress_addpx(_cck_gmapaddress_arrhelper($field['gmap_all']['width'],$view));
		}
		//Map Type Control
		if (strlen($field['gmap_all']['mtc'])>0){
			$settings['mtc'] = _cck_gmapaddress_mtc(_cck_gmapaddress_arrhelper($field['gmap_all']['mtc'],$view));
		}
		
		//Address
		$address = (_cck_gmapaddress_arrhelper($field['gmap_all']['address'],$view))?check_plain(implode(' | ',$addresses)):'';
		
		//Route Link
		$link='';
		if (in_array($view,$field['gmap_all']['routelink'])){
		  $link = cck_gmapaddress_field_formatter($field,$item,'route_all',$node);
		}
		
		return $address.theme_gmap(array('#settings'=>$settings)).$link;
	  } else {
		return '';
	  }
	case 'route_single':
		if (!empty($item['address'])){
			$addresses = array($item['address']);
			_cck_gmapaddress_addroutestartend($field[$formatter]['start'],&$addresses,$field[$formatter]['start_opt'],0);
			_cck_gmapaddress_addroutestartend($field[$formatter]['end'],&$addresses,$field[$formatter]['end_opt'],1);
			return _cck_gmapaddress_routelink($addresses,$field,$field[$formatter]['text']);
		}
		return '';
	case 'route_all':
		//fetches all addresses from node, only in run 1/delta==0
		if ($item['address'] && $item['delta']==0){
		    if (empty($node->{$field['field_name']})){
				$node = node_load($node->nid);
			}
			$addresses=array();
			foreach ($node->{$field['field_name']} as $key=>$el){
				$addresses[] = $el['address'];
			}
			_cck_gmapaddress_addroutestartend($field[$formatter]['start'],$addresses,$field[$formatter]['start_opt'],0);
			_cck_gmapaddress_addroutestartend($field[$formatter]['end'],$addresses,$field[$formatter]['end_opt'],1);
			return _cck_gmapaddress_routelink($addresses,$field,$field[$formatter]['text']);
		}
		return '';	
  }
  return '';
}


function _cck_gmapaddress_accuracy($nr = -1){
 $arr = array(
				0=>t('0 Unknown location'),
				1=>t('1 Country level accuracy'),
				2=>t('2 Region (state, province, prefecture, etc.) level accuracy'),
				3=>t('3 Sub-region (county, municipality, etc.) level accuracy'),
				4=>t('4 Town (city, village) level accuracy'),
				5=>t('5 Post code (zip code) level accuracy'),
				6=>t('6 Street level accuracy'),
				7=>t('7 Intersection level accuracy'),
				8=>t('8 Address level accuracy'),
				9=>t('9 Premise (building name, property name, shopping center, etc.) level accuracy'),
			);
 return ($nr >= 0 && $nr <= 10)?$arr[$nr]:$arr;
}

function _cck_gmapaddress_arrhelper($str,$view='full'){
	$temp = explode(';',$str);
	$arr = array();
	foreach ($temp as $k=>$el){
		$el = explode('=',$el);
		if (strlen($el[1])==0){
			$arr[0]=$el[0];
		} else {
			$arr[$el[0]]=$el[1];
		}
	}
	switch ($view){
		case 'v':
		case 'views':
			return ($arr['v'])?$arr['v']:$arr[0];
		case 't':
		case 'teaser':
			return ($arr['t'])?$arr['t']:$arr[0];
		case 'f':
		case 'full':
			return ($arr['f'])?$arr['f']:$arr[0];
		case 'b':
		case 'block':
			return ($arr['b'])?$arr['b']:$arr[0];
		default:
			return (!$arr[0])?$arr['f']:$arr[0];
	}
}

function _cck_gmapaddress_routestartend($end){
  return array('0'=>t('!nr address',array('!nr'=>($end)?t('Last'):t('First'))),
			  'empty'=>t('Empty Address'),
			  'fix'=>t('Fix Address'),
			  'user' =>t('User field'),
			  );
}

function _cck_gmapaddress_addroutestartend($key,&$addresses,$opt,$end=FALSE){
	switch ($key) {
		case 'empty':
			$val = '-';
			break;
		case 'fix':
			$val = $opt;
			break;
		case 'user':
			GLOBAL $user;
			$array = array();
			user_module_invoke('load', &$array, &$user, $category = NULL);
			$val = _cck_gmapaddress_userfield($opt,$user);
			$val = str_replace(array("\r\n", "\n", "\r"), ", ", $val);
			break;
		default:
			return FALSE;
	}

	return ($end)?array_push(&$addresses,$val):array_unshift(&$addresses,$val);
}

//Add multiple userfields to Address String
function _cck_gmapaddress_userfield($str,&$user,$sep=array(", ",","," ")){
	$vals = array($str);
	$seps = array(0=>"");
	
	foreach ($sep as $k=>$s){
		$vals2 = array();
		$seps2 = array();
		foreach($vals as $n=>$v){
			$arr = explode($s,$v);
			foreach ($arr as $i=>$v2){
			  $vals2[]=$v2;
			  $seps2[]=($i>0)?$s:$seps[$n];
			}
		}
		$vals = $vals2;
		$seps = $seps2;
	}
	$return = '';
	foreach($vals as $k=>$val){
	  if (strlen($val)>0){
		$val = "user->$val";
		$return .= $seps[$k].eval("return \$$val;");
	  }
	}
	return check_plain((strlen($return)>0)?$return:'-');
}

//Append 'px', if no string
function _cck_gmapaddress_addpx($str){
	return (is_int($str))?$str:$str.'px';
}

function _cck_gmapaddress_mtc($val = '-1'){
$arr = array(0 => 'none',
			 1 => 'standard',
			 2 => 'hier',
			 3 => 'menu',
		);
 return $arr[$val];
}

/**
 * Generate GMap Rout Link
 **/
function _cck_gmapaddress_routelink($addresses,$field,$text='',$attributes = array()){
$addresses= array_values($addresses);
$text = ($text)?$text:'Route';

$path = "http://maps.google.".$field['tld']."/maps";
$saddr = '';
$daddr = array();
 
 foreach ($addresses as $nr=>$adr){
	if ($nr>0){
		$daddr[]=$adr;
	} else {
		$saddr = $adr;
	}
 }
 
 return l($text, $path, $attributes, "f=d&saddr=$saddr&daddr=".implode('+to:',$daddr), NULL, TRUE, FALSE);

/** http://maps.google.de/maps?
					f=d
					&hl=de
					&geocode=
					&saddr=Holzminden
					&daddr=Karlsruhe
						+to:bozen
					&mra=pi
					&mrcr=1
					&sll=50.41419,9.002155
					&sspn=4.809747,14.018555
					&ie=UTF8
					&z=6
*/
}

/**
 * Hook_block()
 *
 * Provides some blocks for showing an address or google map in a separate Block.
 */
 function cck_gmapaddress_block($op = 'list', $delta = 0, $edit = array()) {
  $count = variable_get('cck_gmapaddress_count',  1);
  switch ($op) {
    case 'list':
	  for ($i=0;$i < $count;$i++){
		$blocks[$i]['info'] =  t('Gmap Address #@nr',array('@nr'=>$i+1));
	  }
      return $blocks;
	case 'configure':
      $form = array();
      if ($delta == 0) {
		$form['cck_gmapaddress_count'] = array(
          '#type' => 'select',
          '#title' => t('Numbers of GMap Address blocks'),
          '#description' => t('Select, how many blocks shall be configurable.'),
          '#default_value' => variable_get('cck_gmapaddress_count',  1),
		  '#options' => array_combine(range(1,9),range(1,9)),
        ); 
	  }
      $form['cck_gmapaddress_field'] = array(
          '#type' => 'select',
          '#title' => t('Node Reference Field'),
          '#description' => t('The name of the cck GMapAddress field, which content should be presented.'),
          '#default_value' => variable_get("cck_gmapaddress_field_$delta",  ''),
		  '#options' => _cck_gmapaddress_fields(),
      );
	  $form['cck_gmapaddress_formatter'] = array(
          '#type' => 'select',
          '#title' => t('Formatter'),
          '#description' => t('Select a formatter for block view.'),
          '#default_value' => variable_get("cck_gmapaddress_formatter_$delta",  ''),
		  '#options'=>_cck_gmapaddress_formatters(),
      );
      return $form;
    case 'save':
      if ($delta == 0) {
        variable_set("cck_gmapaddress_count", $edit['cck_gmapaddress_count']);
	  }
	  variable_set("cck_gmapaddress_field_$delta", $edit['cck_gmapaddress_field']);
	  variable_set("cck_gmapaddress_formatter_$delta", $edit['cck_gmapaddress_formatter']);
      return;
    case 'view':
      //Zeige GMapAddress in gewähltem Format, falls node
	  $fieldname = variable_get("cck_gmapaddress_field_$delta",  '');
	  if (strlen($fieldname)==0){return '';}
	  $nid = _cck_gmapaddress_getnid($delta);
	  if (!$nid){return '';}
	  $node = node_load($nid);
	  $field = content_fields($fieldname,$node->type);
	  $node_field = $node->$fieldname;
	  $formatter = variable_get("cck_gmapaddress_formatter_$delta",  '');
	  if (!empty($node_field)){
		  foreach ($node_field as $i => $item) {
            $node_field[$i]['view'] = cck_gmapaddress_field_formatter($field, $item, $formatter, $node, TRUE);
          }
		  $block['subject'] = $field['label'];
	      $block['content'] = theme('field', $node, $field, $node_field,NULL,NULL);
	  }
      return $block;
  }
}

function _cck_gmapaddress_fields(){
	$fields = content_fields();
	$return = array();
	foreach ($fields as $field) {
		if ($field['type'] == 'cck_gmapaddress'){
			$return[] = $field['field_name'];
		}
	}
	return array_combine($return,$return);
}

function _cck_gmapaddress_formatters(){
	$return = array();
	$formatters = cck_gmapaddress_field_formatter_info();
	foreach ($formatters as $f=>$info){
		$return[$f]=$info['label'];
	}
	return $return;
}

function _cck_gmapaddress_getblock($delta=0){
	return db_fetch_array(db_query("SELECT pages, visibility, custom, title FROM {blocks} WHERE module = '%s' AND delta = '%s'", 'cck_gmapaddress', $delta));
}

function _cck_gmapaddress_getnid($delta){
	$block = _cck_gmapaddress_getblock($delta);
	$vis = $block['visibility'];	
	$pages = $block['pages'];
	if ($vis == 2){ //php-code
		// take returned int as nid
		return drupal_eval($pages);
	} else {//only listed
		//fetch first integer with *-replacement
		$pages = explode('||',str_replace(array("\r\n", "\n", "\r"), "||", $pages));
		$nid = 0;
		foreach ($pages as $nr=>$page){
			$page = explode('/',$page);
			$nid = 0;
			foreach($page as $n=>$p){
//				print "<br/>P:$p-".arg($n);
				if ($p== '$'){
					$nid = 1*arg($n);
				} elseif ($p == '*' && $nid == 0){
				  $nid = 1*arg($n);
				} elseif ($p != arg($n)){
				  $nid = 0;
				  break;
				}
			}
			if (is_int($nid) && $nid>0 && $vis == 1){
				return $nid;
			} elseif (is_int($nid) && $nid>0 && $vis == 0) {
			    break;  //break, because query is in banned list
			}
		}
	}
	if ($nid != 0){return 0;}
	//fetch first integer as nid, for sites that were not banned
	if ($vis == 0) {
		for ($i=0;$i<=5;$i++){
			$nid = 1*arg($i);
			if ($nid !== ''){
				$nid *= (is_int($nid) && $nid > 0);
				if ($nid>0){ return $nid;}
			}
		}
	}
	
	return $nid;
}

?>