<?php

class vote_function_score extends vote_function {
  function result($result) {
  	if (!isset($this->value)) {	
	  foreach ($result as $item) {
	    $this->value[$item->value] = $item->score;
	  }
  	}
  	
    return $this->value;
  }
  
  function save($values = NULL) {
    $values = !isset($values) ? $this->value : $values;
    $this->value = (array) $values;   

    $output = array();
    
    foreach ($this->value as $choice => $value) {
      if (!$this->is_empty($value) && isset($this->rid[$choice])) {
      	$array['rid'] = $this->rid[$choice];
      	$array['pool'] = $this->pool;
      	$array['entity_type'] = $this->entity_type;
      	$array['entity_id'] = $this->entity_id;
      	$array['function'] = $this->function;
      	$array['choice'] = $choice;
      	$array['value'] = $value;
      	$array['created'] = $this->created;
      	
      	$output[$this->rid($choice)] = array_combine($this->fields, $array);
      }
    }
    
    return $output;
  }
  
  function render($choice) {
    if (isset($this->value[$choice])) {
      return $this->value[$choice];
    }
  }
  
  function rid($choice = NULL) {
    if (!isset($this->rid)) {
      $pool = vote_pool_get($this->pool);

      foreach ($pool->get_allowed_values() as $choice => $value) {
      	$this->rid[$choice] = vote_rid($this, $this->function . ':' . $choice);
      }     
    }
    
    return isset($choice) ? $this->rid[$choice] : $this->rid;
  }
  
  function pool_identifier($new, $old) {      	
    db_update(vote_function_table($this->function))
      ->fields(array('pool' => $new))
      ->condition('pool', $old)
      ->condition('function', $this->function)
      ->expression('rid', 'CONCAT(:pool, :spacer, entity_type, :spacer, entity_id, :spacer, function, :spacer, choice)', array(':pool' => $new, ':spacer' => ':'))
      ->execute();
  }
}

class vote_function_count extends vote_function {
  function result($result) {
    if (!isset($this->value)) {
      $item = current($result);
      $this->value = $item->count;
    }
    
    return $this->value;
  }  
}

class vote_function_average extends vote_function {
  function result($result) {
    if (!isset($this->value)) {
      $item = current($result);
      $this->value = $item->average;
    }
    
    return $this->value;
  }  
}

class vote_function_sum extends vote_function { 
  function result($result) {
    if (!isset($this->value)) {
      $item = current($result);
      $this->value = $item->sum;
    }
    
    return $this->value;
  }
}

class vote_function_broken extends vote_function {
  function broken() { 
    return TRUE; 
  }
  
  function pool_identifier() {      	
  }
  
  function result() {
  }
  
  function save() {
  }
  
  function delete() {
  }  
}

class vote_function {
  var $table = NULL;
  var $fields = NULL;
  var $function = NULL;
  var $pool = NULL;
  var $entity_type = NULL;  
  var $entity_id = NULL;
  var $value = NULL;
  var $created = REQUEST_TIME;
  var $rid = NULL;
  
  function options() {
    $options = array(
      'suffix' => array(
        'singular' => '',
        'plural' => '',
      ),
    );
    
    return $options + parent::options();
  }  
  
  function options_form($form, $form_state) {
    $definition = vote_fetch_function_definition($this->function);
    
    $form['title'] = array(
      '#type' => 'item',
      '#title' => t('Additional settings for %function', array('%function' => $definition['title'])),
    );
    
    if (isset($this->pool) && $pool = vote_pool_get($this->pool)) {
      $form['flush'] = array(
        '#type' => 'submit',
        '#value' => t('Flush all @function results for @pool', array('@function' => $definition['title'], '@pool' => $pool->name)),
        '#submit' => array('vote_admin_flush_function_submit'),
        '#function' => $this->function,
      );
    }
      
    return $form;
  }
  
  function options_form_validate(&$form, &$form_state) {
  }
  
  function options_form_submit(&$form, &$form_state) {
  }
  
   function result($result) {
  }
  
  function save($value = NULL) {
    $value = !isset($value) ? $this->value : $value;
    $this->value = $value;
    $output = array();
    
    if (!$this->is_empty($this->value)) {
      $array['rid'] = $this->rid();
      $array['pool'] = $this->pool;
      $array['entity_type'] = $this->entity_type;
      $array['entity_id'] = $this->entity_id;
      $array['function'] = $this->function;
      $array['value'] = $this->value;
      $array['created'] = $this->created;
      
      $output = array($this->rid() => array_combine($this->fields, $array));
    }
    
    return $output;
  }
  
  function delete() {
    $rid = is_array($this->rid()) ? $this->rid() : array($this->rid());
    
    return drupal_map_assoc($rid);
  }
  
  function is_empty($value = NULL) {
    $value = !isset($value) ? $this->value : $value;
    
    return empty($value) && (string) $value != '0';
  }
  
  function render() {
    if (isset($this->value)) {
      return $this->value;
    }
  }
  
  function rid() {
    if (!isset($this->rid)) {
      $this->rid = vote_rid($this, $this->function);
    } 
    
    return $this->rid;
  }
  
  function pool_identifier($new, $old) {   	
    db_update(vote_function_table($this->function))
      ->fields(array('pool' => $new))
      ->condition('pool', $old)
      ->condition('function', $this->function)
      ->expression('rid', 'CONCAT(:pool, :spacer, entity_type, :spacer, entity_id, :spacer, function)', array(':pool' => $new, ':spacer' => ':'))
      ->execute();
  }
  
  function broken() {
    return FALSE;
  }
}