<?php

namespace common\models;

use Yii;
use yii\base\Model;

use yii\base\InvalidParamException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use yii\data\Pagination;
use yii\helpers\Url;
use yii\helpers\Html;

/**
 * instructions
 * this model provides a structure for the form.
 * here you can modify all the parameter for the content of the form:
 * mainly fields and their types
 * and also some othr parameter such as which string is shown
 * in a selection list as default
 *
 * how to define fields:
 * you have to add each field to the
 * field definitions section ,
 * field declarationss section and
 * the rules() function
 * (see below at the corresponding section for further infos)
 *
 * you also have to define what queries are generated from the user
 * input of each field. do this in the QueryFactory.
 * make sure you use the same name in all 4 places!
 * and is the same name as in the correspondint solr index field!
 *
 * you also can add a label for the field in the attributeLabels() function
 * by default the label is generatet automatically
 * by changing camelcase to single words
 * and start each word upper case
 * e.g. familyName will get the label: Family Name
 *
 * you also can define more form parameters in the other settings section
 * (see below)
 *
 * this form is used by the SearchController
 * that runs the search view (views.search.search.php) customized for this model.
 *
 * @author s.buers
 *        
 */
class CommonSearchForm extends Model {
	
	/*
	 * ----------------- common settings ----------------------------
	 */
	// title of the form; These default settings can be customized in app/models/SearchForm (will overwrite the variables below)
	private $_extendedSearchFormTitle = 'SEARCH';
	private $_previewTitle = 'RESULTS OVERVIEW';
	private $_detailsTitle = 'DETAILS';
	
	// search button text:
	private $_extendedSearchButtonLabel = 'Search'; // Rukeia 16-02-2015: Das ist das Search-Button-Label.
	private $_refineSearchButtonLabel = 'Refine search';
	private $_newSearchButtonLabel = 'New search';
	
	private $_saveSearchButtonLabel = 'Save Search'; // Hartebrodt 22-07-15
	private $_searchName; //Hartebrodt 23-07-15: name a search to store it in the database
	                                                
	// what string represents if nothing is chosen in the drop down lists
	// (technically it leads to everything (*))
	private $_selectionListNonChosen = "---";
	
	// string that is presented in a suggestion list if
	// the input does not match to any item
	private $_sugesstionListNoMatch = "-- no match --";
	
	// default size of fields
	// - if you don't give a size in the definition area this value will be used
	private $_fieldSize = 50;
	
	// ---- keep your hands off these parameters---------------
	// ------they will be initialized automatically (e.g see init())
	private $_hideableList = [ ];
	private $_hideableListFields = [ ];
	private $_completeList = [ ]; // Rukeia 30-03-2015: added
	private $_completeListFields = [ ]; // Rukeia 30-03-2015: added
	
	private $dropDownAttributes;
	public $_selectionlists;
	
	public $key_link = 'fullScientificName';
	public $submitURL;
	
	public $recordFilters = array (
			'unitID',
			'collectioncode',
			'institutioncode'
	);
	                                    
	// ------------- getters--------------------------------------
	public function getParameters() {
		return $this->_parameters;
	}
	public function getExtendedSearchFormTitle() {
		return $this->_extendedSearchFormTitle;
	}
	public function getPreviewTitle() {
		return $this->_previewTitle;
	}
	public function getDetailsTitle() {
		return $this->_detailsTitle;
	}
	public function getExtendedSearchButtonLabel() {
		return $this->_extendedSearchButtonLabel;
	}
	public function getNewSearchButtonLabel() {
		return $this->_newSearchButtonLabel;
	}
	public function getRefineSearchButtonLabel() {
		return $this->_refineSearchButtonLabel;
	}
	public function getFieldsPerRow() {
		return $this->_fieldsPerRow;
	}
	public function getSelectionListNonChosen() {
		return $this->_selectionListNonChosen;
	}
	public function getSugesstionListNoMatch() {
		return $this->_sugesstionListNoMatch;
	}
	public function getHideableList() {
		return $this->_hideableList;
	}
	public function getHideableListFields() {
		return $this->_hideableListFields;
	}
	public function getCompleteList() { // Rukeia 30-03-2015: added
		return $this->_completeList;
	}
	public function getCompleteListFields() { // Rukeia 30-03-2015: added
		return $this->_completeListFields;
	}
	public function getFieldSize() {
		return $this->_fieldSize;
	}
	
	/*
	 * ----------------- field declarations ------------------------
	 * put here all the same fields as you defined in the parameters array
	 */
	// voucher/specimen
	
	public $speciesName;
	public $genusName;
	public $familyName;
	public $orderName;
	public $className;
	public $phylumName;
	public $kingdomName;
	public $fullScientificName; // Species //TODO have also search with * like "ac*" ***main field***
	public $name;
	public $taxonomyId; // TODO later, not yet in index
	public $identifiedBy;
	public $country; // ***main field***
	public $isocountrycode;
	public $continent; // TODO
	public $sea; // TODO
	public $ocean; // TODO
	public $longitudeFrom;
	public $longitudeTo;
	public $latitudeFrom;
	public $latitudeTo;
	public $collectionYearFrom;
	public $collectionYearTo;
	public $locality;
	public $collectors;
	public $collectornumber;
	public $hasTypestatus;  // boolean
	public $hasImage; // boolean
	public $unitID;
	public $cites;
	public $sampleavailability;

	public $institution;
	public $voucherCol;
	public $indexHerbarorium;
	
	public $sequenceaccessionIdentifier;
	public $geneticlocus;
	public $kingdom;
	public $tripleidstoreid;
	public $collectioncode;
	public $institutioncode;

	public $genBankRecordAvailable;
	public $sampletype;
	public $ipen;
	public $accessionStatus = 'onlyLiving';
	public $unitaccessionnumber;
	public $recordbasis;
	public $preparationtype;
	
	
	// @override
	public function init() {
		foreach ( $this->_parameters as $key => $attr ) {
			if (isset ( $attr ['hideable'] ) && $attr ['hideable'] == 'true') {
				$this->_hideableList [] = $key;
				$this->_hideableListFields [] = $attr ['name'];
			}
			
			// Rukeia 30-03-2015: added
			$this->_completeList [] = $key;
			$this->_completeListFields [] = $attr ['name'];
		}
	}
	
	// ----------------- validation rules ------------------------
	// @override
	/**
	 * Declares the validation rules.
	 * each field that has no rules has to be at least assigned to the 'safe' validator
	 */
	
	
	public function rules() {
// 		Yii::info ( "RULES VALIDATION" );
		return [ 
				[ ['fullScientificName', 'kingdom', 'phylumName','className','orderName','familyName','genusName','speciesName','geneticlocus','collectioncode',
						'institutioncode','locality','collectors','collectornumber','cites','sampleavailability','sequenceaccessionIdentifier',
						'unitID','ipen','unitaccessionnumber','hasImage','hasTypestatus','country','recordbasis','isocountrycode','continent',
						'sea','ocean','sampletype','preparationtype','institution','latitudeFrom','latitudeTo','longitudeFrom','longitudeTo',
						'collectionYearFrom','collectionYearTo','accessionStatus','identifiedBy'
				],
						/*,'ScientificName','speciesName',
						*/
				 	'match', 'pattern'=>'/^[^<>;]*$/', 'message'=>'invalid entry'],
				[ 
						[ 
								'unitID',
								'fullScientificName' 
						],
						'trim' 
				],
				[ 
						[ 
								'latitudeFrom',
								'latitudeTo' 
						],
						'number',
						'min' => - 90,
						'max' => 90 
				],
				[ 
						[ 
								'longitudeFrom',
								'longitudeTo' 
						],
						'number',
						'min' => - 180,
						'max' => 180 
				],
				[ 
						[ 
								'latitudeFrom',
								'latitudeTo',
								'longitudeFrom',
								'longitudeTo' 
						],
						'makedouble' 
				],
				[ 
						[ 
								'collectionYearFrom',
								'collectionYearTo' 
						],
						'default',
						'value' => null 
				],
				[ 
						[ 
								'collectionYearFrom',
								'collectionYearTo' 
						],
						'date',
						'format' => 'yyyy' 
				] 
		]
		// [['latitudeFrom','latitudeTo'],'isLatitude'],
		// [['longitudeFrom','longitudeTo'],'isLongitude'],
		
		;
	}
	
	/*
	 * validator for coordinates
	 */
	public function makedouble($attribute) {
// 		Yii::info ( "makedouble" );
		return $attribute*1.0;
	}
	
	// ------------ functions --------------------
	public function collectDropDownAttributesLists($model) {
		if (! isset ( $this->dropDownAttributes )) {
			$this->dropDownAttributes = array ();
				
			foreach ( $model->getParameters () as $name => $list ) {
				if (isset ( $list ['type'] ) && $list ['type'] == 'select') {
					array_push ( $this->dropDownAttributes, $name );
				}
			}
		}
		if (! isset ( $this->_selectionlists )) {
			$this->_selectionlists = FormSelectionQueryManager::getAllLists ( $this->dropDownAttributes, $model->getSelectionListNonChosen () );
		}
		return $this->_selectionlists;
	}
	
	public function createUrl($destination, $formParameters) {
		$nonEmptyFormParameters = array_filter ( $formParameters, 'strlen' );
		unset ( $nonEmptyFormParameters ['yt0'] );
		return Yii::$app->getUrlManager ()->createUrl ( $destination, $nonEmptyFormParameters );
	}
	
}