<?php
/**
 * @package    JBusinessDirectory
 *
 * @author CMSJunkie http://www.cmsjunkie.com
 * @copyright  Copyright (C) 2007 - 2021 CMSJunkie. All rights reserved.
 * @license   https://www.gnu.org/licenses/agpl-3.0.en.html
 */
defined('_JEXEC') or die('Restricted access');

jimport('joomla.application.component.modeladmin');
require_once(HELPERS_PATH.'/category_lib.php');
require_once BD_CLASSES_PATH.'/attributes/attributeservice.php';
use Joomla\Utilities\ArrayHelper;

/**
 * Company Model for Companies.
 *
 */
class JBusinessDirectoryModelEvent extends JModelAdmin {
	/**
	 * @var		string	The prefix to use with controller messages.
	 * @since   1.6
	 */
	protected $text_prefix = 'COM_JBUSINESSDIRECTORY_EVENT';
	protected $error_row = 0;
	protected $tableHeader;
	protected $failedEvents = array();
	protected $newEventsCount = 0;
	protected $header = array();
	protected $headerDifferences = array();
	protected $categories;
	protected $countries;
	protected $languages;

	/**
	 * Model context string.
	 *
	 * @var		string
	 */
	protected $_context		= 'com_jbusinessdirectory.event';

	/**
	 * JBusinessDirectoryModelEvent constructor.
	 * @param array $config
	 */
	public function __construct($config = array()) {
		$this->appSettings = JBusinessUtil::getApplicationSettings();

		parent::__construct($config);
	}
	/**
	 * Method to test whether a record can be deleted.
	 *
	 * @param   object	A record object.
	 *
	 * @return  boolean  True if allowed to delete the record. Defaults to the permission set in the component.
	 */
	protected function canDelete($record) {
		return true;
	}

	/**
	 * Method to test whether a record can be deleted.
	 *
	 * @param   object	A record object.
	 *
	 * @return  boolean  True if allowed to change the state of the record. Defaults to the permission set in the component.
	 */
	protected function canEditState($record) {
		return true;
	}

	/**
	 * Returns a Table object, always creating it
	 *
	 * @param   type	The table type to instantiate
	 * @param   string	A prefix for the table class name. Optional.
	 * @param   array  Configuration array for model. Optional.
	 * @return  JTable	A database object
	 */
	public function getTable($type = 'Event', $prefix = 'JTable', $config = array()) {
		return JTable::getInstance($type, $prefix, $config);
	}
	
	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @since   1.6
	 */
	protected function populateState() {
		$app = JFactory::getApplication('administrator');

		// Load the User state.
		$id = JFactory::getApplication()->input->getInt('id');
		$this->setState('event.id', $id);
	}

	/**
	 * Method to get a menu item.
	 *
	 * @param   integer	The id of the menu item to get.
	 *
	 * @return  mixed  Menu item data object on success, false on failure.
	 */
	public function &getItem($itemId = null) {
		$itemId = (!empty($itemId)) ? $itemId : (int) $this->getState('event.id');
		$false	= false;

		// Get a menu item row instance.
		$table = $this->getTable("Event");

		// Attempt to load the row.
		$return = $table->load($itemId);

		// Check for a table object error.
		if ($return === false && $table->getError()) {
			$this->setError($table->getError());
			return $false;
		}

		$properties = $table->getProperties(1);
		$value = ArrayHelper::toObject($properties, 'JObject');

		$companyTable = $this->getTable('Company');
		if (!empty($value->id)) {
			$value->companyOptions = array($companyTable->getCompany($value->company_id));
		}
		
		$typesTable = $this->getTable('EventType');
		$value->types = $typesTable->getEventTypes();

		if ($this->appSettings->enable_multilingual) {
			JBusinessDirectoryTranslations::updateEventTypesTranslation($value->types);
		}
		
		if ($this->appSettings->enable_multilingual) {
			JBusinessDirectoryTranslations::updateEventTypesTranslation($value->types);
		}
				
		$value->pictures = $this->getEventPictures((int) $this->getState('event.id'));

		$videosTable = $this->getTable('EventVideos');
		$value->videos = $videosTable->getEventVideos($itemId);

		if ($itemId == 0) {
			$value->start_date = date('Y-m-d');
			$value->end_date = date("Y-m-d");// current date
			
			$value->booking_open_date = date('Y-m-d');
			$value->booking_close_date = date('Y-m-d');
			$value->currency_id = $this->appSettings->currency_id;
		}

		if ($value->booking_open_date == '0000-00-00' || empty($value->booking_open_date)) {
			$value->booking_open_date = null;
		}
		if ($value->booking_close_date == '0000-00-00'|| empty($value->booking_close_date)) {
			$value->booking_close_date = null;
		}
		if ($value->start_date == '0000-00-00' || empty($value->start_date)) {
			$value->start_date = null;
		}
		if ($value->end_date == '0000-00-00' || empty($value->end_date)) {
			$value->end_date = null;
		}

		$value->start_date = JBusinessUtil::convertToFormat($value->start_date);
		$value->end_date = JBusinessUtil::convertToFormat($value->end_date);

		if ($value->id == 0) {
			$value->time_zone = $this->appSettings->default_time_zone;
		}

		if ($value->start_time != '00:00:00') {
			$value->start_time = JBusinessUtil::convertTimeToFormat($value->start_time);
		} else {
			$value->start_time = null;
		}

		if ($value->end_time != '00:00:00') {
			$value->end_time = JBusinessUtil::convertTimeToFormat($value->end_time);
		} else {
			$value->end_time = null;
		}

		if ($value->doors_open_time != '00:00:00') {
			$value->doors_open_time = JBusinessUtil::convertTimeToFormat($value->doors_open_time);
		} else {
			$value->doors_open_time = null;
		}

		if ($value->booking_open_time != '00:00:00') {
			$value->booking_open_time = JBusinessUtil::convertTimeToFormat($value->booking_open_time);
		} else {
			$value->booking_open_time = null;
		}

		if ($value->booking_close_time != '00:00:00') {
			$value->booking_close_time = JBusinessUtil::convertTimeToFormat($value->booking_close_time);
		} else {
			$value->booking_close_time = null;
		}

		if(!empty($value->countryId)){
			$regionTable = $this->getTable('Region');
			$value->regions = $regionTable->getRegionsByCountry($value->countryId);
		}

		if(!empty($value->county)){
			$cityTable = $this->getTable('City');
			$value->cities = $cityTable->getCitiesByRegionName($value->county);
		}

		$recurringElements = $table->getAllSeriesEventsIds($itemId);
		if (count($recurringElements)>1 && empty($value->recurring_id)) {
			$value->recurring_id = $itemId;
		}
		
		// Get selected associated companies
		$associatedCompaniesTable = $this->getTable('EventAssociatedCompanies');
		if (!empty($itemId)) {
			$value->selectedCompanies = $associatedCompaniesTable->getAssociatedCompaniesByEvent($itemId);
		} else {
			$value->selectedCompanies= array();
		}
		
		if (!empty($value->selectedCompanies)) {
			$value->associatedCompaniesOptions = $associatedCompaniesTable->getAssociatedCompanyOptions($itemId);
		} else {
			$value->associatedCompaniesOptions = array();
		}
		
		$companyCategoryTable = $this->getTable('CompanyCategory');
		$value->selectedCategories = $companyCategoryTable->getSelectedEventCategories($itemId);

		$companyCategoryTable = $this->getTable('CompanyCategory');
		$value->selectedSubCategories = $companyCategoryTable->getSelectedEventCategoriesList($itemId);

		foreach ($value->selectedSubCategories as $cat) {
			$cat->name = str_repeat('- ', $cat->level-1) . $cat->name;
		}

		$categoryId = $this->appSettings->enable_attribute_category?$value->main_subcategory:null;
		$attributesTable = $this->getTable('EventAttributes');
		$value->customFields = $attributesTable->getEventAttributes($itemId, $categoryId);

		if ($this->appSettings->enable_multilingual) {
			JBusinessDirectoryTranslations::updateAttributesTranslation($value->customFields);
		}

		$value->defaultAtrributes = JBusinessUtil::getAttributeConfiguration(DEFAULT_ATTRIBUTE_TYPE_EVENT);

		$countriesTable = $this->getTable('Country');
		$value->countries = $countriesTable->getCountries();
		JBusinessDirectoryTranslations::updateCountriesTranslation($value->countries);

		$value->attachments = JBusinessDirectoryAttachments::getAttachments(EVENTS_ATTACHMENTS, $itemId);

		return $value;
	}
	
	
	public function getEventPictures($eventId) {
		$query = "SELECT * FROM #__jbusinessdirectory_company_event_pictures
					WHERE eventId =".$eventId ."
					ORDER BY id ";
		
		$files =  $this->_getList($query);
		$pictures = array();
		foreach ($files as $value) {
			$pictures[] = array(
				'id' => $value->id,
				'picture_title' => $value->picture_title,
				'picture_info' => $value->picture_info,
				'picture_path' => $value->picture_path,
				'picture_enable' => $value->picture_enable,
			);
		}
	
		return $pictures;
	}

	/**
	 * Method to get the menu item form.
	 *
	 * @param   array  $data		Data for the form.
	 * @param   boolean	$loadData	True if the form is to load its own data (default case), false if not.
	 * @return  JForm	A JForm object on success, false on failure
	 * @since   1.6
	 */
	public function getForm($data = array(), $loadData = true) {
		
		// The folder and element vars are passed when saving the form.
		if (empty($data)) {
			$item		= $this->getItem();
			// The type should already be set.
		}
		// Get the form.
		$form = $this->loadForm('com_jbusinessdirectory.event', 'item', array('control' => 'jform', 'load_data' => $loadData), true);
		if (empty($form)) {
			return false;
		}
		
		return $form;
	}

	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  mixed  The data for the form.
	 * @since   1.6
	 */
	protected function loadFormData() {
		// Check the session for previously entered form data.
		$data = JFactory::getApplication()->getUserState('com_jbusinessdirectory.edit.event.data', array());

		if (empty($data)) {
			$data = $this->getItem();
		}

		return $data;
	}
	
	/**
	 * Check if the entered dates are valid
	 * @param unknown_type $data
	 */
	
	public function checkDates(&$data) {
		if (!empty($data["start_date"]) && !empty($data["end_date"])) {
			if (strtotime($data["start_date"]) > strtotime($data["end_date"])) {
				JFactory::getApplication()->enqueueMessage(JText::_('LNG_END_DATE_LOWER_THAN_START_DATE'), 'warning');
				$data["end_date"] = $data["start_date"];
			} elseif (strtotime($data["start_date"]) == strtotime($data["end_date"])) {
				if (!empty($data["start_time"]) && !empty($data["end_time"]) && strtotime($data["start_time"]) > strtotime($data["end_time"])) {
					JFactory::getApplication()->enqueueMessage(JText::_('LNG_END_TIME_LOWER_THAN_START_TIME'), 'warning');
				}
			}
		}
		
		if (!empty($data["booking_open_date"]) && !empty($data["booking_close_date"])) {
			if (!empty($data["booking_open_date"]) && !empty($data["booking_close_date"])) {
				if (strtotime($data["booking_open_date"]) > strtotime($data["booking_close_date"])) {
					JFactory::getApplication()->enqueueMessage(JText::_('LNG_BOOKING_END_DATE_LOWER_THAN_START_DATE'), 'warning');
					$data["booking_close_date"] = $data["booking_open_date"];
				}
			}
		
			if (!empty($data["booking_open_time"]) && !empty($data["booking_close_time"])) {
				if (strtotime($data["booking_open_time"]) > strtotime($data["booking_close_time"])) {
					JFactory::getApplication()->enqueueMessage(JText::_('LNG_BOOKING_END_TIME_LOWER_THAN_START_TIME'), 'warning');
				}
			}
		}
	}
	
	/**
	 * Check for duplicate alias and generate a new alias
	 * @param unknown_type $busienssId
	 * @param unknown_type $alias
	 */
	public function checkAlias($eventId, $alias) {
		$table = $this->getTable();
		while ($table->checkAlias($eventId, $alias)) {
			$alias = Joomla\String\StringHelper::increment($alias, 'dash');
		}
		return $alias;
	}
	
	/**
	 * Method to save the form data.
	 *
	 * @param   array  The form data.
	 * @return  boolean  True on success.
	 */
	public function save($data) {
		//dump($data);exit;
		$id	= (!empty($data['id'])) ? $data['id'] : (int) $this->getState('event.id');
		$data['id'] =$id;
		$isNew = $id > 0? false:true;

		foreach ($data as &$item) {
			if (!is_array($item)) {
				$item = trim($item);
			}
		}
		
		if (!$this->appSettings->item_decouple) {
			if (!$this->checkPackageLimit($data["company_id"], $isNew, $id)) {
				JFactory::getApplication()->enqueueMessage(JText::_('LNG_PACKAGE_LIMIT_EXCEEDED'), 'warning');
				// reset company id
				$data["company_id"] = 0;
			}
		}else{
			if(empty($data["company_id"])){
                $data["company_id"] = -1;
            }
		}

		$controller = substr($data["task"], 0, strpos($data["task"], "."));
		if ($data["user_id"]!='0' && $controller == "managecompanyevent") {
			if ($this->appSettings->enable_item_moderation == '0') {
				$data["approved"] = EVENT_APPROVED;
			} else {
				//if number of threshold is 0 then approve else check the number of approved items of this user
				if ($this->appSettings->enable_automated_moderation) {
					if ($this->appSettings->moderate_threshold == '0') {
						$data["approved"] = EVENT_APPROVED;
					} else {
						$table = $this->getTable('Event');
						$totalApprovedUserItems = $table->getTotalUserEvents(array(), $data["user_id"], true);
						if ($totalApprovedUserItems >= $this->appSettings->moderate_threshold) {
							$data["approved"] = EVENT_APPROVED;
						}
					}
				}
			}
		}

		if (!empty($data["start_date"]) && $data["start_date"]!= '0000-00-00 00:00:00') {
			$data["start_date"] = JBusinessUtil::convertToMysqlFormat($data["start_date"]);
		} else {
			$data["start_date"] = null;
		}

		if (!empty($data["end_date"])) {
			$data["end_date"] = JBusinessUtil::convertToMysqlFormat($data["end_date"]);
		} else {
			$data["end_date"] = null;
		}

		if (!empty($data["booking_open_date"]) && $data["booking_open_date"]!= '0000-00-00 00:00:00') {
			$data["booking_open_date"] = JBusinessUtil::convertToMysqlFormat($data["booking_open_date"]);
		} else {
			$data["booking_open_date"] = null;
		}

		if (!empty($data["booking_close_date"])) {
			$data["booking_close_date"] = JBusinessUtil::convertToMysqlFormat($data["booking_close_date"]);
		} else {
			$data["booking_close_date"] = null;
		}

		$input =JFactory::getApplication()->input;
		$data["show_end_date"] = isset($data["show_end_date"])?$data["show_end_date"]:$input->get('show_end_date', 0);
		$data["show_start_time"] = isset($data["show_start_time"])?$data["show_start_time"]:$input->get('show_start_time', 0);
		$data["show_end_time"] = isset($data["show_end_time"])?$data["show_end_time"]:$input->get('show_end_time', 0);
		$data["show_doors_open_time"] = isset($data["show_doors_open_time"])?$data["show_doors_open_time"]:$input->get('show_doors_open_time', 0);

		if ($data["start_time"] == '') {
			$data["show_start_time"] = null;
		}

		if ($data["end_time"] == '') {
			$data["show_end_time"] = null;
		}

		if ($data["doors_open_time"] == '') {
			$data["show_doors_open_time"] = null;
		}

		if ($data["attendance_mode"] == '') {
			$data["attendance_mode"] = null;
		}

		if (empty($data['start_time'])) {
			$data['start_time'] = '00:00:00';
		} else {
			$data["start_time"] = JBusinessUtil::convertTimeToMysqlFormat($data["start_time"]);
		}
		if (empty($data['end_time'])) {
			$data['end_time'] = '00:00:00';
		} else {
			$data["end_time"] = JBusinessUtil::convertTimeToMysqlFormat($data["end_time"]);
		}
		if (empty($data['doors_open_time'])) {
			$data['doors_open_time'] = '00:00:00';
		} else {
			$data["doors_open_time"] = JBusinessUtil::convertTimeToMysqlFormat($data["doors_open_time"]);
		}
		if (empty($data['booking_open_time'])) {
			$data['booking_open_time'] = '00:00:00';
		} else {
			$data["booking_open_time"] = JBusinessUtil::convertTimeToMysqlFormat($data["booking_open_time"]);
		}
		if (empty($data['booking_close_time'])) {
			$data['booking_close_time'] = '00:00:00';
		} else {
			$data["booking_close_time"] = JBusinessUtil::convertTimeToMysqlFormat($data["booking_close_time"]);
		}

		if (!empty($data["latitude"])) {
			$data["latitude"] = filter_var($data['latitude'], FILTER_SANITIZE_NUMBER_FLOAT, array('flags' => FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND));
		}
		
		if (!empty($data["longitude"])) {
			$data["longitude"] = filter_var($data['longitude'], FILTER_SANITIZE_NUMBER_FLOAT, array('flags' => FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND));
		}

		if (empty($data['total_tickets'])) {
			$data['total_tickets'] = 0;
		}

		if (empty($data['min_age'])) {
			$data['min_age'] = null;
		}

		if (empty($data['max_age'])) {
			$data['max_age'] = null;
		}
		
		$defaultLng = JBusinessUtil::getLanguageTag();
		$description = $input->get("description_".$defaultLng, '', 'RAW');
		$short_description = $input->get("short_description_".$defaultLng, '', 'RAW');
		$name = $input->get("name_".$defaultLng, '', 'RAW');
		$meta_title = $input->get("meta_title_".$defaultLng, '', 'RAW');
		$meta_desc = $input->get("meta_description_".$defaultLng, '', 'RAW');
		$meta_key = $input->get("meta_keywords_".$defaultLng, '', 'RAW');


		if ((!empty($meta_key) && empty($data["meta_keywords"])) || !isset($data["meta_keywords"])) {
			$data["meta_keywords"] = $meta_key;
		}

		if ((!empty($meta_title) && empty($data["meta_title"])) || !isset($data["meta_title"])) {
			$data["meta_title"] = $meta_title;
		}

		if ((!empty($meta_desc) && empty($data["meta_description"])) || !isset($data["meta_description"])) {
			$data["meta_description"] = $meta_desc;
		}

		if (!empty($name) && empty($data["name"])) {
			$data["name"] = $name;
		}

		if (!empty($description) && empty($data["description"])) {
			$data["description"] = $description;
		}

		if (empty($data["short_description"])) {
			$data["short_description"] = $short_description;
		}

		if (!isset($data["preserve_alias"])) {
			$data["alias"]= JBusinessUtil::getAlias($data["name"], $data["alias"]);
			$data["alias"] = $this->checkAlias($id, $data["alias"]);
		}

		if (!empty($data["has_recurring"])) {
			if ($data["recurring_id"] == $id) {
				$data["recurring_id"] = 0;
			}
		}
		if (isset($data['frequency']) && $data['frequency'] != 0) {
			$data["recurring_info"] = $this->getReccuringInfo($data);
		}

		if (!empty($data["countryId"])) {
			$data["countryId"] = (int) $data["countryId"];
		} else {
			$data["countryId"] = 0;
		}

		$data["description"] = JBusinessUtil::removeRelAttribute($data["description"]);

		// delete main category if not present in data
		if (!isset($data["main_subcategory"]) || empty('main_subcategory')) {
			$data["main_subcategory"] = null;
		}
		
		$this->checkDates($data);

		// Get a row instance.
		$table = $this->getTable();

		// Load the row if saving an existing item.
		if ($id > 0) {
			$table->load($id);
			$isNew = false;
		}

		// Bind the data.
		if (!$table->bind($data)) {
			$this->setError($table->getError());
			dump($table->getError());
			return false;
		}

		// Check the data.
		if (!$table->check()) {
			$this->setError($table->getError());
			dump($table->getError());
			return false;
		}

		// Store the data.
		if (!$table->store()) {
			$this->setError($table->getError());
			dump($table->getError());
			return false;
		}

		$this->setState('event.id', $table->id);
		$this->setState('com_jbusinessdirectory.edit.managecompanyevent.id', $table->id);

		if (!empty($data["has_recurring"])) {
			if (!empty($data["frequency"])) {
				$table->recurring_id = $this->getState('parent.event.id');
				$table->store();
			}
		}
		$id = $table->id;
		$properties = $table->getProperties(1);
		$event = ArrayHelper::toObject($properties, 'JObject');

		// Clean the cache
		$this->cleanCache();

		if ($isNew && empty($data["no-email"])) {
			EmailService::sendNewEventNotification($table);
		}

		JBusinessDirectoryAttachments::saveAttachments(EVENTS_ATTACHMENTS, EVENT_ATTACHMENTS_PATH, $table->id, $data, $id);

		// if no category is selected, create a dummy relation with categoryId = -1 so that
		// the insertEventRelations function deletes all other existing relations
		if (!isset($data['categories'])) {
			$data['categories'] = array(-1);
		}
		
		if (!empty($data["categories"])) {
			$table = $this->getTable('CompanyCategory');
			$table->insertEventRelations($this->getState('event.id'), $data["categories"]);
		}

		try {
			$this->storeAttributes($this->getState('event.id'), $data);

			$oldId = $isNew?0:$id;
			$this->storePictures($data, $this->getState('event.id'), $oldId);

			$this->storeVideos($data, $this->getState('event.id'));
		} catch (Exception $ex) {
			$this->setError($ex->getMessage());
		}

		//save associated companies data
		$associatedCompaniesTable = $this->getTable('EventAssociatedCompanies');
		$assListings = !empty($data["associated-listings"])?$data["associated-listings"]:null;
		$associatedCompaniesTable->storeAssociatedCompanies($this->getState('event.id'), $assListings, array(-11));

		$imported = isset($data['imported'])?true:false;
		JBusinessDirectoryTranslations::saveTranslations(EVENT_DESCRIPTION_TRANSLATION, $this->getState('event.id'), 'description_', false, $imported, $data);
		JBusinessDirectoryTranslations::saveTranslations(EVENT_META_TRANSLATION, $this->getState('event.id'), '', true, $imported, $data);

		JFactory::getApplication()->triggerEvent('onAfterJBDSaveEvent', array($event,$isNew));
		
		return true;
	}

	public function storePictures($data, $eventId, $oldId) {
		$usedFiles = array();
		if (!empty($data['pictures'])) {
			foreach ($data['pictures'] as $value) {
				array_push($usedFiles, $value["picture_path"]);
			}
		}

		$pictures_path = JBusinessUtil::makePathFile(BD_PICTURES_UPLOAD_PATH);
		$event_pictures_path = JBusinessUtil::makePathFile(EVENT_PICTURES_PATH.($eventId)."/");
		JBusinessUtil::removeUnusedFiles($usedFiles, $pictures_path, $event_pictures_path);
	
		//dbg($eventId);

		//exit;
		$picture_ids 	= array();
		foreach ($data['pictures'] as $value) {
			$row = $this->getTable('EventPictures');
	
			//dbg($key);
			$pic 						= new stdClass();
			$pic->id		= 0;
			$pic->eventId 	= $eventId;
			$pic->picture_title	= $value['picture_title'];
			$pic->picture_info	= $value['picture_info'];
			$pic->picture_path	= $value['picture_path'];
			$pic->picture_enable = $value['picture_enable'];
			//dbg($pic);
			$pic->picture_path = JBusinessUtil::moveFile($pic->picture_path, $eventId, $oldId, EVENT_PICTURES_PATH);

			if (!$row->bind($pic)) {
				throw( new Exception($row->getError()) );
				$this->setError($row->getError());
			}
			// Make sure the record is valid
			if (!$row->check()) {
				throw( new Exception($row->getError()) );
				$this->setError($row->getError());
			}
	
			// Store the web link table to the database
			if (!$row->store()) {
				throw( new Exception($row->getError()) );
				$this->setError($row->getError());
			}
	
			$picture_ids[] = $this->_db->insertid();
		}

		$query = " DELETE FROM #__jbusinessdirectory_company_event_pictures
		WHERE eventId = '".$eventId."'
		".(count($picture_ids)> 0 ? " AND id NOT IN (".implode(',', $picture_ids).")" : "");
	
		// dbg($query);
		
		$this->_db->setQuery($query);
		try {
			$this->_db->execute();
		} catch (RuntimeException $e) {
			$this->setError($e->getMessage());
			return false;
		}
	}
	
	public function createRecurringEvents($parentId, $data) {
		//dump("createRecurringEvents");
		//        dump($parentId);
		//        dump($data);exit;
		$table = $this->getTable();
		$table->deleteReccuringEvents($parentId);
		
		$dates = $this->getReccuringDates($data);
	
		$data["recurring_id"]=$parentId;
		foreach ($dates as $date) {
			$this->setState('parent.event.id', $parentId);
			$this->setState('event.id', $table->id);
			$data["id"]=0;
			$data["start_date"] = $date[0];
			$data["end_date"] =	$date[1];
			$data["approved"] =	$data["approved"];
			$this->save($data);
		}
	}
	
	public function updateRecurringEvents($parentId, $data) {
		$table = $this->getTable();
		$table->deleteReccuringEvents($parentId);
	}

	public function getReccuringInfo($data) {
		$recurringInfo = new stdClass();
		switch ($data['frequency']) {
			case 1:
				$recurringInfo->frequency = JText::_("LNG_DAILY");
				break;
			case 2:
				$recurringInfo->frequency = JText::_("LNG_WEEKLY");
				break;
			case 3:
				$recurringInfo->frequency = JText::_("LNG_MONTHLY");
				break;
			default:
				$recurringInfo->frequency = JText::_("LNG_YEARLY");
				break;
		}

		$recurringInfo->interval = $data["interval"];
		$recurringInfo->start_date = $data["start_date"];
		if ($data['endson'] == 1) {
			$recurringInfo->occurrences = isset($data["occurrences"])?$data["occurrences"]:0;
		} else {
			$recurringInfo->end_date = isset($data["rend_date"])?$data["rend_date"]:"";
		}

		if ($data["frequency"] == 2) {
			if (isset($data["week_days"])) {
				foreach ($data['week_days'] as &$week_day) {
					if ($week_day == 0) {
						$week_day = 7;
					}
					$week_day = JBusinessUtil::getWeekdayFromIndex($week_day);
				}
			}
			$recurringInfo->week_days = $data["week_days"];
		} elseif ($data["frequency"] == 3) {
			$recurringInfo->repeatby = ($data["repeatby"]==1)?JText::_("LNG_DAY_OF_MONTH"):JText::_("LNG_DAY_OF_WEEK");
		}

		return json_encode($recurringInfo);
	}
	
	public function getReccuringDates($data) {
		$dates = array();
		$data["start_date"] = JBusinessUtil::convertToMysqlFormat($data["start_date"]);
		$data["end_date"] = JBusinessUtil::convertToMysqlFormat($data["end_date"]);
		$data["rend_date"] =  isset($data["rend_date"])?JBusinessUtil::convertToMysqlFormat($data["rend_date"]):"";
		
		$eventPeriod = JBusinessUtil::getNumberOfDays($data["start_date"], $data["end_date"]);
		
		$frequency = $data["frequency"];
		$interval = $data["interval"];
		$rstart_date = $data["start_date"];
		$endson = $data["endson"];
		$week_days = isset($data["week_days"])?$data["week_days"]:"";
		$repeatby = $data["repeatby"];
		$occurrences = isset($data["occurrences"])?$data["occurrences"]:0;
		$occurrences--;
		$rend_date = isset($data["rend_date"])?$data["rend_date"]:"";
		$count = 0;
		
		switch ($frequency) {
			case 1:
				$create = true;
				$startDate = $rstart_date;
				while ($create) {
					$startDate = date("Y-m-d", strtotime("+$interval days", strtotime($startDate)));
					$endDate = date("Y-m-d", strtotime("+$eventPeriod days", strtotime($startDate)));
					$date = array($startDate,$endDate);
						
					if ($endson ==1  && $count>$occurrences) {
						$create = false;
					}
					if ($endson ==2 && strtotime($endDate)>=strtotime($rend_date)) {
						$create = false;
					}
						
					if ($create) {
						$dates[] = $date;
						$count++;
					}
					
					if ($count>100) {
						exit;
					}
				}
				break;
			case 2:
				$create = true;
				$weekDate = $rstart_date;
				
				while ($create) {
					$week_start = date('Y-m-d', strtotime('this week last monday', strtotime($weekDate)));
					foreach ($week_days as $weekday) {
						$weekday--;
						$startDate = date("Y-m-d", strtotime("+$weekday days", strtotime($week_start)));
						$endDate = date("Y-m-d", strtotime("+$eventPeriod days", strtotime($startDate)));
						$date = array($startDate,$endDate);
						if ($endson ==1  && $count>$occurrences) {
							$create = false;
						}
		
						if ($endson ==2 && strtotime($endDate)>=strtotime($rend_date)) {
							$create = false;
						}
		
						if ($create && strtotime($startDate)>strtotime($rstart_date)) {
							$dates[] = $date;
							$count++;
						}
					}
					$weekDate = date("Y-m-d", strtotime("+$interval weeks", strtotime($weekDate)));
				}
				break;
			case 3:
				$create = true;
				$monthDate = $rstart_date;
				$day = strtotime($rstart_date);
				$weekNumber = date('W', $day) - date('W', strtotime(date('Y-m-01', $day)))-1;
				$dayOfWeek = date('l', $day);
				$numbermappings = array("first", "second","third","fourth","fifth");
		
				while ($create) {
					$startDate ="";
					$endDate ="";
					$month_start = strtotime('first day of this month', strtotime($monthDate));
					//dump(date("Y-m-d",$month_start));
					if ($repeatby == 1) {
						$dayMonth = date("d", strtotime($monthDate))-1;
						$startDate = date("Y-m-d", strtotime("+$dayMonth days", $month_start));
						$endDate = date("Y-m-d", strtotime("+$eventPeriod days", strtotime($startDate)));
					} else {
						$startDate = date("Y-m-d", strtotime(" $numbermappings[$weekNumber] $dayOfWeek ", $month_start));
						$endDate = date("Y-m-d", strtotime("+$eventPeriod days", strtotime($startDate)));
					}
		
					$date = array($startDate,$endDate);
		
					if ($endson ==1  && $count>$occurrences) {
						$create = false;
					}
					if ($endson ==2 && strtotime($endDate)>=strtotime($rend_date)) {
						$create = false;
					}
		
					if ($create & strtotime($startDate)>strtotime($rstart_date)) {
						$dates[] = $date;
						$count++;
					}
					
					if ($count>3000) {
						exit;
					}
						
					$monthDate = date("Y-m-d", strtotime("+$interval months", strtotime($monthDate)));
				}
				break;
			case 4:
				$yearDate = $rstart_date;
				$create = true;
				while ($create) {
					$startDate = date("Y-m-d", strtotime($yearDate));
					$endDate = date("Y-m-d", strtotime("+$eventPeriod days", strtotime($startDate)));
		
					$date = array($startDate,$endDate);
		
					if ($endson ==1  && $count>$occurrences) {
						$create = false;
					}
						
					if ($endson ==2 && strtotime($endDate)>=strtotime($rend_date)) {
						$create = false;
					}
		
					if ($create & strtotime($startDate)>strtotime($rstart_date)) {
						$dates[] = $date;
						$count++;
					}
					
					$yearDate = date("Y-m-d", strtotime("+$interval years", strtotime($yearDate)));
				}
				break;
		}
		
		return $dates;
	}
	
	public function getNextEventsIds($eventId) {
		$eventsTable = $this->getTable("Event");
		$eventsTable->load($eventId);
	
		return $eventsTable->getNextEventsIds($eventsTable->id, $eventsTable->recurring_id);
	}
	
	public function getAllSeriesEventsIds($eventId) {
		$eventsTable = $this->getTable("Event");
		$eventsTable->load($eventId);
		$id = $eventsTable->recurring_id;
		if (empty($eventsTable->recurring_id)) {
			$id = $eventId;
		}
		return $eventsTable->getAllSeriesEventsIds($id);
	}
	
	public function deleteEvent($eventId) {
		$eventsTable = $this->getTable("Event");
		return $eventsTable->delete($eventId);
	}
	
	public function changeState($id = null) {
		if (empty($id)) {
			$id = JFactory::getApplication()->input->getInt('id');
		}
		$this->populateState();
		$eventsTable = $this->getTable("Event");
		return $eventsTable->changeState($id);
	}
	
	public function changeStateEventOfTheDay() {
		$this->populateState();
		$eventsTable = $this->getTable("Event");
		return $eventsTable->changeStateEventOfTheDay($this->getState('event.id'));
	}
	
	public function changeStateFeatured($id) {
		$eventTable = $this->getTable("Event");
		return $eventTable->changeStateFeatured($id);
	}
	
	
	public function changeAprovalState($state) {
		$this->populateState();
		$eventsTable = $this->getTable("Event");
		$event = $eventsTable->getEvent($this->getState('event.id'));

		$companiesTable = JTable::getInstance("Company", "JTable");
		$company = $companiesTable->getCompany($event->company_id);
		
		if ($event->approved ==0 and $state==1) {
			EmailService::sendApproveEventNotification($event, $company);
		}

		return $eventsTable->changeAprovalState($this->getState('event.id'), $state);
	}
	
	public function getCompanies() {
		$companiesTable = JTable::getInstance("Company", "JTable");
		$companies =  $companiesTable->getAllCompanies();
		return $companies;
	}
	
	public function getStates() {
		$states = array();
		$state = new stdClass();
		$state->value = 0;
		$state->text = JTEXT::_("LNG_INACTIVE");
		$states[] = $state;
		$state = new stdClass();
		$state->value = 1;
		$state->text = JTEXT::_("LNG_ACTIVE");
		$states[] = $state;
	
		return $states;
	}
	
	public function getStatuses() {
		$statuses = array();
		$status = new stdClass();
		$status->value = 0;
		$status->text = JTEXT::_("LNG_NEEDS_CREATION_APPROVAL");
		$statuses[] = $status;
		$status = new stdClass();
		$status->value = 1;
		$status->text = JTEXT::_("LNG_DISAPPROVED");
		$statuses[] = $status;
		$status = new stdClass();
		$status->value = 2;
		$status->text = JTEXT::_("LNG_APPROVED");
		$statuses[] = $status;
	
		return $statuses;
	}

	public function getCurrencies() {
		$currencyTable = $this->getTable('Currency');
		$currencies = $currencyTable->getCurrencies();

		return $currencies;
	}

	/**
	 * Method to delete groups.
	 *
	 * @param   array  An array of item ids.
	 * @return  boolean  Returns true on success, false on failure.
	 */
	public function delete(&$itemIds) {
		// Sanitize the ids.
		$itemIds = (array) $itemIds;
		ArrayHelper::toInteger($itemIds);
	
		// Get a group row instance.
		$table = $this->getTable();
	
		// Iterate the items to delete each one.
		foreach ($itemIds as $itemId) {
			if (!$table->delete($itemId)) {
				$this->setError($table->getError());
				return false;
			}
			
			if (!$this->deleteFiles($itemId)) {
				$this->setError("Could not delete files");
				return false;
			}

			if (!$table->deleteAllDependencies($itemId)) {
				$this->setError($table->getError());
				return false;
			}

			JBusinessDirectoryTranslations::deleteTranslationsForObject(EVENT_DESCRIPTION_TRANSLATION, $itemId);
		}
	
		// Clean the cache
		$this->cleanCache();
	
		return true;
	}
	
	/**
	 * Delete event files
	 * @param $itemId
	 * @return boolean
	 */
	public function deleteFiles($itemId) {
		$imagesDir = BD_PICTURES_UPLOAD_PATH .EVENT_PICTURES_PATH.($itemId);
		JBusinessUtil::removeDirectory($imagesDir);

		$attachmentDir = BD_ATTACHMENT_UPLOAD_PATH .EVENT_ATTACHMENTS_PATH.$itemId;
		JBusinessUtil::removeDirectory($attachmentDir);
	
		return true;
	}

	public function storeAttributes($eventId, $data) {
		#delete all ad attributes
		
		$attrTable =$this->getTable('EventAttributes');
		$attrIds=array();
		foreach ($data as $key => $value) {
			#save ad attributes
			if (strpos($key, "attribute")===0) {
				$attributeArr = explode("_", $key);
				if (!empty($attributeArr[1])) {
					$attrIds[]=$attributeArr[1];
				}
			}
			if (strpos($key, "delete_attribute")===0) {
				$attributeArr = explode("_", $key);
				if (!empty($attributeArr[2])) {
					$attrIds[]=$attributeArr[2];
				}
			}
		}
		
		$attrIds = array_unique($attrIds);

		if (!empty($attrIds) && !$attrTable->deleteEventAttributes($eventId, $attrIds)) {
			$this->setError(JText::_("LNG_ERROR_DELETING_AD_ATTRIBUTES").$attrTable->getError());
		}
		
		foreach ($data as $key => $value) {
			#save ad attributes
			if (strpos($key, "attribute")===0) {
				$attributeArr = explode("_", $key);
				//print_r($attributeArr);
				$eventAttributeTable =$this->getTable('EventAttributes');
				$eventAttributeTable->event_id= $eventId;
				if(is_int($value)){
					$eventAttributeTable->option_id= $value;
				}
				$eventAttributeTable->value= $value;
				$eventAttributeTable->attribute_id= $attributeArr[1];

				if (is_array($eventAttributeTable->value)) {
					$eventAttributeTable->value = implode(",", $eventAttributeTable->value);
				}

				$properties = $eventAttributeTable->getProperties(1);
				$value = ArrayHelper::toObject($properties, 'JObject');

				if (!$eventAttributeTable->store()) {
					$this->setError(JText::_("LNG_ERROR_SAVING_AD_ATTRIBUTES").$eventAttributeTable->getError());
				}
			}
		}
	}

	/**
	 * Method to perform batch operations on an item or a set of items.
	 *
	 * @param   array  $commands  An array of commands to perform.
	 * @param   array  $pks       An array of item ids.
	 * @param   array  $contexts  An array of item contexts.
	 *
	 * @return  boolean  Returns true on success, false on failure.
	 *
	 * @since   12.2
	 */
	public function batch($vars, $pks, $contexts) {
		// Sanitize ids.
		$pks = array_unique($pks);
		ArrayHelper::toInteger($pks);

		// Remove any values of zero.
		if (array_search(0, $pks, true)) {
			unset($pks[array_search(0, $pks, true)]);
		}

		if (empty($pks)) {
			$this->setError(JText::_('JGLOBAL_NO_ITEM_SELECTED'));

			return false;
		}

		$done = false;

		// Set some needed variables.
		$this->user = JBusinessUtil::getUser();
		$this->table = $this->getTable();
		$this->tableClassName = get_class($this->table);
		$this->batchSet = true;
		// Parent exists so let's proceed
		while (!empty($pks)) {
			// Pop the first ID off the stack
			$pk = array_shift($pks);

			$this->table->reset();

			// Check that the row actually exists
			if (!$this->table->load($pk)) {
				if ($error = $this->table->getError()) {
					// Fatal error
					$this->setError($error);

					return false;
				} else {
					// Not fatal error
					$this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk));
					continue;
				}
			}

			// set new approval state
			if ($vars["approval_status_id"]!="") {
				$this->table->approved = $vars["approval_status_id"];
			}

			// set new approval state
			if ($vars["featured_status_id"]!="") {
				$this->table->featured = $vars["featured_status_id"];
			}

			// set new approval state
			if ($vars["state_id"]!="") {
				$this->table->state = $vars["state_id"];
			}

			// Check the row.
			if (!$this->table->check()) {
				$this->setError($this->table->getError());

				return false;
			}

			// Store the row.
			if (!$this->table->store()) {
				$this->setError($this->table->getError());

				return false;
			}
		}

		// Clean the cache
		$this->cleanCache();

		return true;
	}

	public function getImportStatus() {
		$result = new stdClass();
		$result->differences = $this->headerDifferences;
		$result->correctHeader = $this->tableHeader;
		$result->failedEvents = $this->failedEvents;
		$result->newEvents = $this->newEventsCount;

		if ($result->differences) {
			$msg = JText::_('LNG_NOT_RECOGNIZED_HEADERS')."<br />".implode(", ", $result->differences);
			JFactory::getApplication()->enqueueMessage($msg, 'warning');
			$msg = JText::_('LNG_ALLOWED_HEADER')."<br />".implode(", ", $result->correctHeader);
			$msg .= "<br /><br />";
			JFactory::getApplication()->enqueueMessage($msg, 'success');
		}

		if ($result->failedEvents) {
			$message = JText::_('LNG_IMPORT_FAILED_FOR');
			JFactory::getApplication()->enqueueMessage(JText::_('LNG_IMPORT_FAILED_FOR'), 'warning');
			foreach ($result->failedEvents as $item) {
				$message = $message.JFactory::getApplication()->enqueueMessage(JText::_('LNG_ROW') . " " . $item->row . "  " . JText::_('LNG_EVENT_NAME') . " " . $item->name, 'warning');
			}
		}

		if ($result->newEvents) {
			$message = JText::plural('COM_JBUSINESS_DIRECTORY_N_EVENTS_IMPORTED', $result->newEvents);
			JFactory::getApplication()->enqueueMessage($message, 'success');
		}

		return $result;
	}

	public function importEvents($event) {
		if (isset($event["name"])) {
			$updateExisting = JFactory::getApplication()->input->get("update_existing");
			$datas = array();
			$subCategoryId = "";
			if (!empty($event["categories"])) {
				$categoriesNames = explode(",", $event["categories"]);
				foreach ($categoriesNames as $category) {
					if (empty($category)) {
						continue;
					}

					//dump("search ".$category);
					$cat = $this->getCategoryByName($this->categories, $category);
					//	dump($cat[0]->name);
					if (!isset($cat)) {
						continue;
					}
					$categoryIds[] = $cat[0]->id;

					if (!empty($event["main_subcategory"]) && $event["main_subcategory"] == $category) {
						$subCategoryId = $cat[0]->id;
					}
				}
				$datas["categories"] = $categoryIds;
				$datas["main_subcategory"] = $subCategoryId;
			}			

			$countryId = 0;
			if (isset($event["country"])) {
				if (isset($this->countries[$event["country"]])) {
					$countryId = $this->countries[$event["country"]]->id;
				}
			}

			$datas["id"] = isset($event["id"]) ? $event["id"] : "";			
			if (isset($updateExisting)) {
				$eventsTable = $this->getTable("Event");
				$actualevent = $eventsTable->getEventByName($event["name"]);
				$datas["id"] = $actualevent->id;
			}		
			$datas["name"] = isset($event["name"]) ? $event["name"] : "";
			$datas["alias"] = !empty($event["alias"]) ? $event["alias"] : "";
			$datas["alias"] = JBusinessUtil::getAlias($event["name"], $event["alias"]);
			$datas["company_id"] = isset($event["company_id"]) ? $event["company_id"] : "";
			$datas["company"] = isset($event["company"]) ? $event["company"] : "";
			$datas["currency_id"] = isset($event["currency_id"]) ? $event["currency_id"] : "";
			$datas["description"] = isset($event["description"]) ? $event["description"] : "";
			$datas["short_description"] = isset($event["short_description"]) ? $event["short_description"] : "";
			$datas["description"] = isset($event["description"]) ? $event["description"] : "";
			$datas["meta_title"] = isset($event["meta_title"]) ? $event["meta_title"] : "";
			$datas["meta_description"] = isset($event["meta_description"]) ? $event["meta_description"] : "";
			$datas["meta_keywords"] = isset($event["meta_keywords"]) ? $event["meta_keywords"] : "";
			$datas["price"] = isset($event["price"]) ? $event["price"] : "";
			$datas["eventType"] = isset($event["eventType"]) ? $event["eventType"] : "";
			$datas["type"] = isset($event["type_id"]) ? $event["type_id"] : "";
			$datas["Start_Date"] = isset($event["Start_Date"]) ? $event["Start_Date"] : "";
			$datas["start_date"] = isset($event["start_date"]) ? $event["start_date"] : "";
			$datas["end_date"] = isset($event["end_date"]) ? $event["end_date"] : "";
			$datas["start_time"] = isset($event["start_time"]) ? $event["start_time"] : "";
			$datas["end_time"] = isset($event["end_time"]) ? $event["end_time"] : "";
			$datas["approved"] = isset($event["approved"]) ? $event["approved"] : 1;
			$datas["address"] = isset($event["address"]) ? $event["address"] : "";
			$datas["city"] = isset($event["city"]) ? $event["city"] : "";
			$datas["county"] = isset($event["county"]) ? $event["county"] : "";
			$datas["location"] = isset($event["location"]) ? $event["location"] : "";
			$datas["latitude"] = isset($event["latitude"]) ? $event["latitude"] : "";
			$datas["longitude"] = isset($event["longitude"]) ? $event["longitude"] : "";
			
			if(!empty($company["created"])){
				$categoryData["created"] =  $company["created"];
			}
			if(!empty($company["modified"])){
				$categoryData["modified"] =  $company["modified"];
			}

			$datas["view_count"] = isset($event["view_count"]) ? $event["view_count"] : "";
			$datas["state"] = isset($event["state"]) ? $event["state"] : 1;
			$datas["recurring_id"] = isset($event["recurring_id"]) ? $event["recurring_id"] : "";
			$datas["contact_phone"] = isset($event["contact_phone"]) ? $event["contact_phone"] : "";
			$datas["contact_email"] = isset($event["contact_email"]) ? $event["contact_email"] : "";
			$datas["doors_open_time"] = isset($event["doors_open_time"]) ? $event["doors_open_time"] : "";
			$datas["booking_open_date"] = isset($event["booking_open_date"]) ? $event["booking_open_date"] : "";
			$datas["booking_close_date"] = isset($event["booking_close_date"]) ? $event["booking_close_date"] : "";
			$datas["booking_open_time"] = isset($event["booking_open_time"]) ? $event["booking_open_time"] : "";
			$datas["booking_close_time"] = isset($event["booking_close_time"]) ? $event["booking_close_time"] : "";
			$datas["show_start_time"] = isset($event["show_start_time"]) ? $event["show_start_time"] : "";
			$datas["show_end_time"] = isset($event["show_end_time"]) ? $event["show_end_time"] : "";
			$datas["show_end_date"] = isset($event["show_end_date"]) ? $event["show_end_date"] : "";
			$datas["show_doors_open_time"] = isset($event["show_doors_open_time"]) ? $event["show_doors_open_time"] : "";
			$datas["total_tickets"] = isset($event["total_tickets"]) ? $event["total_tickets"] : "";
			$datas["expiration_email_date"] = isset($event["expiration_email_date"]) ? $event["expiration_email_date"] : "";
			$datas["featured"] = isset($event["featured"]) ? $event["featured"] : "";
			$datas["pictures"] = isset($event["pictures"]) ? $event["pictures"] : "";
			$datas["province"] = isset($event["province"]) ? $event["province"] : "";
			$datas["area"] = isset($event["area"]) ? $event["area"] : "";
			$datas["user_id"] = isset($event["user_id"]) ? $event["user_id"] : "";
			$datas["no-email"] = 1;
			$datas["countryId"] = (int) $countryId;
			$datas["postalCode"] = isset($event["postal_code"]) ? $event["postal_code"] : "";
			$datas["street_number"] = isset($event["street_number"]) ? $event["street_number"] : "";
			
			$datas["attendance_mode"] = isset($event["attendance_mode"]) ? $event["attendance_mode"] : "";
			
			$attendanceModes = JBusinessUtil::getAttendanceModes();
			foreach($attendanceModes as $md){
				if($md->text == $datas["attendance_mode"]){
					$datas["attendance_mode"] = $md->value;
				}
			}
			$datas["attendance_url"] = isset($event["attendance_url"]) ? $event["attendance_url"] : "";

			foreach ($this->languages as $lng) {
				$datas["name_".strtolower($lng)] = isset($event["name_".strtolower($lng)]) ? $event["name_".strtolower($lng)] : "";
				$datas["short_description_".strtolower($lng)] = isset($event["short_description_".strtolower($lng)]) ? $event["short_description_".strtolower($lng)] : "";
				$datas["description_".strtolower($lng)] = isset($event["description_".strtolower($lng)]) ? $event["description_".strtolower($lng)] : "";
				$datas["meta_title_".strtolower($lng)] = isset($event["meta_title_".strtolower($lng)]) ? $event["meta_title_".strtolower($lng)] : "";
				$datas["meta_description_".strtolower($lng)] = isset($event["meta_description_".strtolower($lng)]) ? $event["meta_description_".strtolower($lng)] : "";
				$datas["meta_keywords_".strtolower($lng)] = isset($event["meta_keywords_".strtolower($lng)]) ? $event["meta_keywords_".strtolower($lng)] : "";
			}
			$datas["imported"] = true;

			if (!empty($datas["pictures"])) {
				$datas["pictures"] = explode(",", $datas["pictures"]);
				$pictures = [];
				foreach ($datas["pictures"] as $key => $picture) {
					$picturesData = explode('#', $picture);

					$picTmp = [];
					$picTmp['picture_title'] = $picturesData[1];
					$picTmp['picture_info'] = $picturesData[2];
					$picTmp['picture_path'] = $picturesData[0];
					$picTmp['picture_enable'] = 1;

					$pictures[] = $picTmp;
				}
				$datas['pictures'] = $pictures;
			}

			//load custom attributes
			$attributesTable = JTable::getInstance("Attribute", "JTable");
			$attributes = $attributesTable->getAttributesWithTypes();

			$attributesTable = JTable::getInstance("AttributeOptions", "JTable");
			$attributeOptions = $attributesTable->getAllAttributesWithOptions();

			foreach ($attributes as $attribute) {
				$attribute->name = 'attribute_'.strtolower($attribute->name);

				if (!empty($event[$attribute->name])) {
					$attrValues = $event[$attribute->name];
					$attrValues = explode(",", $attrValues);
					foreach ($attrValues as $value) {
						if ($attribute->attr_type == "input" || $attribute->attr_type == "textarea" || $attribute->attr_type == "link") {
							$datas["attribute_" . $attribute->id][] = $event[$attribute->name];
							break;
						} else {
							foreach ($attributeOptions as $attributeOption) {
								if ($this->appSettings->enable_multilingual) {
									$attributeOption->name = JBusinessDirectoryTranslations::getTranslatedItemName($attributeOption->name);
								}
								if ($attributeOption->attr_id == $attribute->id && $attributeOption->name == $value) {
									$datas["attribute_" . $attribute->id][] = $attributeOption->id;
								}
							}
						}
					}
				}
			}

			try {
				$this->setState('event.id', 0);
				$this->error_row++;
				if ($this->save($datas)) {
					$this->newEventsCount++;
				} else {
					$failedEvent = new stdClass();
					$failedEvent->name = $datas["name"];
					$failedEvent->row = $this->error_row;
					array_push($this->failedEvents, $failedEvent);
				}
			} catch (Exception $e) {
				dump($e);
			}
		} else {
			$failedEvent = new stdClass();
			$this->error_row++;
			$failedEvent->name = JText::_('LNG_UNKNOWN');
			;
			$failedEvent->row = $this->error_row;
			array_push($this->failedEvents, $failedEvent);
		}

	}

	public function getCountries() {
		$result = array();
		$countriesTable = $this->getTable("Country");
		$countries = $countriesTable->getCountries();
		foreach ($countries as $country) {
			$result[$country->country_name] = $country;
		}

		return $result;
	}

	/**
	 * Check if headers on the file that will be imported are OK
	 * @return bool
	 */
	public function checkHeaders() {
		$attributesTable = JTable::getInstance("Attribute", "JTable");
		$attributes = $attributesTable->getAttributes();

		$this->tableHeader = array();

		array_push(
			$this->tableHeader,
			"company_id",
			"id",
			"name",
			"alias",
			"short_description",
			"description",
			"meta_title",
			"meta_description",
			"meta_keywords",
			"price",
			"type_id",
			"start_date",
			"start_time",
			"end_date",
			"end_time",
			"address",
			"city",
			"county",
			"location",
			"latitude",
			"longitude",
			"featured",
			"created",
			"view_count",
			"approved",
			"state",
			"recurring_id",
			"contact_phone",
			"contact_email",
			"doors_open_time",
			"booking_open_date",
			"booking_close_date",
			"booking_open_time",
			"booking_close_time",
			"show_start_time",
			"show_end_time",
			"show_end_date",
			"show_doors_open_time",
			"currency_id",
			"total_tickets",
			"expiration_email_date",
			"main_subcategory",
			"province",
			"area",
			"postal_code",
			"country",
			"street_number",
			"user_id",
			"pictures",
			"eventType",
			"company",
			"categories",
			"attendance_mode",
			"attendance_url"
		);

		if (!empty($attributes)) {
			foreach ($attributes as $attribute) {
				array_push($this->tableHeader, 'attribute_'.$attribute->name);
			}
		}

		foreach ($this->languages as $lng) {
			array_push($this->tableHeader, "name_$lng");
			array_push($this->tableHeader, "short_description_$lng");
			array_push($this->tableHeader, "description_$lng");
			array_push($this->tableHeader, "meta_title_$lng");
			array_push($this->tableHeader, "meta_description_$lng");
			array_push($this->tableHeader, "meta_keywords_$lng");
		}

		$headerDifferences = array_diff($this->header, $this->tableHeader);
		if (!empty($headerDifferences)) {
			$this->headerDifferences = $headerDifferences;
			return false;
		}
		return true;
	}

	/**
	 * Prepare the file content to be inserted on database
	 * @param string $filePath
	 * @param string $delimiter
	 */
	public function importEventsFromCSV($filePath, $delimiter) {
		$row = 1;
		$this->countries = $this->getCountries();
		$this->categories = $this->getCategories();
		$this->languages = JBusinessUtil::getLanguages();
		ini_set("auto_detect_line_endings", "1");
		if (($handle = fopen($filePath, "r")) !== false) {
			while (($data = fgetcsv($handle, 9000, $delimiter)) !== false) {
				$eventData = array();

				if ($row == 1) {
					$this->header = $data;
					$this->checkHeaders();
					$row ++;
					continue;
				}
				$num = count($data);

				//echo "<p> $num fields in line $row: <br /></p>\n";
				for ($c = 0; $c < $num; $c++) {
					$eventData[strtolower($this->header[$c])] = $data[$c];
				}

				$this->importEvents($eventData);

				if (in_array("id", $this->header)){
					JFactory::getApplication()->enqueueMessage(JText::_('LNG_ID_COLUMN_DETECTED_WARNING'), 'warning');
				}
				$row++;
			}
		}
	}

	/**
	 * Prepare the file content to be inserted on database
	 * @param array $csvContent
	 * @param string $delimiter
	 */
	public function importEventsFromTextArea($csvContent, $delimiter) {
		$row = 1;
		$this->categories = $this->getCategories();
		foreach ($csvContent as $key => $content) {
			$data = str_getcsv($content, $delimiter);
			$eventData=array();

			if ($row == 1) {
				$this->header = $data;
				$this->checkHeaders();
				$row ++;
				continue;
			}

			$num = count($data);
			for ($c = 0; $c < $num; $c++) {
				$eventData[strtolower($this->header[$c])] = $data[$c];
			}

			$this->importEvents($eventData);
			$row++;
		}
	}

	/**
	 * Method to check if actual number of events belonging to
	 * a company has exceeded it's package limits
	 *
	 * @param $companyId int ID of the company
	 * @param $isNew boolean Company if is new of exists
	 * @param $id int Id of the offer
	 * @return bool true if it does not exceed, false otherwise
	 */
	public function checkPackageLimit($companyId, $isNew, $id) {
		if (empty($companyId)) {
			return false;
		}

		$maxEvents = $this->appSettings->max_events;
		if ($this->appSettings->enable_packages) {
			$packagesTable = $this->getTable('Package', 'JTable');
			$package = $packagesTable->getCompanyPackage($companyId);

			if (empty($package)) {
				return false;
			}

			$maxEvents = $package->max_events;
		}

		$eventTable = $this->getTable();
		$nrEvents = (int)$eventTable->getTotalEventsByCompany($companyId);
		$increment = $isNew?1:0;

		$event = $eventTable->getEvent($id);

		if ($maxEvents != 0) {
			if ($maxEvents != $nrEvents) {
				if ((($nrEvents + $increment) > $maxEvents)) {
					return false;
				}
			} elseif ($event->company_id == $companyId) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}

		return true;
	}

	public function getCategoryByName($categories, $categoryName) {
		$categoryService = new JBusinessDirectorCategoryLib();
		$cat = null;
		$category = $categoryService->findCategoryByName($categories, $cat, $categoryName);

		return $category;
	}

	public function getCategories() {
		$categoryService = new JBusinessDirectorCategoryLib();
		$categoryTable = $this->getTable("Category", "JBusinessTable");
		$categories = $categoryTable->getAllCategories(CATEGORY_TYPE_EVENT);
		$categories = $categoryService->processCategoriesByName($categories);
		return $categories;
	}

	/**
	 *
	 * save all the event videos
	 *
	 * @param $data object the event details
	 * @param $eventId int the event if
	 * @throws Exception
	 */
	public function storeVideos($data, $eventId) {
		$table = $this->getTable('EventVideos');
		$table->deleteAllForEvent($eventId);

		foreach ($data['videos'] as $value) {
			if (empty($value)) {
				continue;
			}

			$row = $this->getTable('EventVideos');

			$video = new stdClass();
			$video->id =0;
			$video->eventId = $eventId;
			$video->url = $value;

			if (!$row->bind($video)) {
				throw( new Exception($row->getError()) );
				$this->setError($row->getError());
			}
			// Make sure the record is valid
			if (!$row->check()) {
				throw( new Exception($row->getError()) );
				$this->setError($row->getError());
			}

			// Store the web link table to the database
			if (!$row->store()) {
				throw( new Exception($row->getError()) );
				$this->setError($row->getError());
			}
		}
	}

	/**
	 * Method that retrieves custom attributes based on a certain category in order to be
	 * rendered in HTML.
	 * If multilingual is also enabled, it will translate the attributes.
	 *
	 * @param $categoryId int ID of the category
	 * @param $eventId int ID of the event
	 *
	 * @return string html output
	 */
	public function getAttributesAjax($categoryId, $eventId) {
		$attributesTable = $this->getTable('Attribute');
		$customFields = $attributesTable->getAttributesByCategory($categoryId, ATTRIBUTE_TYPE_EVENT, $eventId);

		foreach ($customFields as $val) {
			if (!isset($val->attributeValue)) {
				$val->attributeValue = '';
			}
		}

		if (!empty($customFields)) {
			if ($this->appSettings->enable_multilingual) {
				JBusinessDirectoryTranslations::updateAttributesTranslation($customFields);
			}

			$renderedContent = AttributeService::renderAttributes($customFields, false, array());
		} else {
			$renderedContent = null;
		}

		return $renderedContent;
	}

	/**
	 * Retrieve Event Listing based on the Listing Id
	 *
	 * @param $companyId int Listing id of the event
	 * @return mixed All listing details
	 */
	public function getListing($companyId) {
		$companyTable = JTable::getInstance("Company", "JTable");
		$company = $companyTable->getCompany($companyId);

		$appSettings = JBusinessUtil::getApplicationSettings();
		if ($appSettings->limit_cities_regions) {
			$table            = $this->getTable('Company');
			$company->regions = $table->getCompanyRegions($company->id);
			$company->cities  = $table->getCompanyCities($company->id);

			if (!empty($company->regions)) {
				$company->county = $company->regions[0]->name;
			}

			if (!empty($company->cities)) {
				$company->city = $company->cities[0]->name;
			}
		}

		return $company;
	}

	/**
	 * Get all regions or by country (based on country ID)
	 *
	 * @param null $countryId int ID of the country
	 *
	 * @return mixed
	 *
	 * @since 4.9.4
	 */
	public function getRegions($countryId = null) {
		$table = $this->getTable('Region', 'JTable');

		if (empty($countryId)) {
			$regions = $table->getRegions();
		} else {
			$regions = $table->getRegionsByCountry($countryId);
		}

		return $regions;
	}

	/**
	 * Get all cities or by region (based on region name)
	 *
	 * @param null $region string name of the region
	 *
	 * @return mixed
	 *
	 * @since 4.9.4
	 */
	public function getCities($region = null) {
		$table = $this->getTable('City', 'JTable');

		if (empty($region)) {
			$cities = $table->getCities();
		} else {
			$cities = $table->getCitiesByRegionName($region);
		}

		return $cities;
	}

	/*
	 * Retrieve the currect active package for a listing
	 */
	public function getPackage($companyId = null) {
		if (empty($companyId)) {
			$companyId = $this->companyId;
		}
		$table = $this->getTable("Package");
		$package = $table->getCurrentActivePackage($companyId);

		return $package;
	}
}
