<?php
/**
 * @version        1.9.13
 * @package        Joomla
 * @subpackage     EDocman
 * @author         Tuan Pham Ngoc
 * @copyright      Copyright (C) 2011 - 2024 Ossolution Team
 * @license        GNU/GPL, see LICENSE.php
 */

// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\Utilities\ArrayHelper;
use Joomla\Database\DatabaseQuery;

class EDocmanModelList extends OSModelList
{
	/**
	 * Include documents from children categories or not
	 *
	 * @var bool
	 */
	private $includeChildrenCategory = false;

	function __construct($config = array())
	{
		$config['table'] = '#__edocman_documents';
        $searchFields = [];
        $searchFields[] = 'tbl.title';
        $searchFields[] = 'tbl.alias';
        $searchFields[] = 'tbl.description';
        $searchFields[] = 'tbl.short_description';
       // $searchFields[] = 't.tag';
        $config['search_fields'] = $searchFields;
		parent::__construct($config);

		// Insert state variables
		$this->state->insert('id', 'int', 0)
			->insert('filter_category_ids', 'string', '')
			->insert('filter_categories_ids', 'string', '')
			->insert('exclude_category_ids', 'string', '')
			->insert('filter_category_id', 'int', 0)
			->insert('filter_search', 'string', '')
			->insert('filter_filetype','string','')
			->insert('filter_datetype','string','created')
			->insert('filter_startdate','string','')
            ->insert('filter_created_user','int',0)
            ->insert('document_id','int',0)
            ->insert('filter_related_documents','int',0)
			->insert('filter_enddate','string','')
            ->insert('filter_tags', 'array', array())
			->insert('filter_indicators','string','')
			->insert('searchphrase', 'string', 'all' )
			->insert('view','string','');

		// Set default value for model states in case it is set in Configuration of the component
		$componentConfig = EDocmanHelper::getConfig();
		
		if ($componentConfig->number_documents)
		{
			$this->state->setDefault('limit', $componentConfig->number_documents);
		}

		if ($componentConfig->default_sort_option)
		{
			$this->state->setDefault('filter_order', $componentConfig->default_sort_option);
		}

		if ($componentConfig->default_sort_direction)
		{
			$this->state->setDefault('filter_order_Dir', $componentConfig->default_sort_direction);
		}

		$this->state->insert('filter_order','string',$componentConfig->default_sort_option);
		$this->state->insert('filter_order_Dir','string',$componentConfig->default_sort_direction);
	}

    /**
     * Builds JOIN clauses for the query
     *
     * @param JDatabaseQuery $query
     *
     * @return $this
     */
    protected function _buildQueryJoins(DatabaseQuery $query)
    {
        //$query->join('LEFT', '#__edocman_document_tags as td on td.document_id = tbl.id')
         //   ->join('LEFT', '#__edocman_tags as t on td.tag_id = t.id');
        return $this;
    }

	/**
	 * Builds SELECT columns list for the query
	 *
	 * @param JDatabaseQuery $query
	 *
	 * @return $this
	 */
	protected function _buildQueryColumns(DatabaseQuery $query)
	{
		$now = Factory::getDate()->toSql();
		$query->select(array('tbl.*', "DATEDIFF('$now', created_time) AS number_created_days", "DATEDIFF('$now', modified_time) AS number_updated_days"));

		return $this;
	}

	/**
	 * Builds WHERE clauses for the query
	 *
	 * @param JDatabaseQuery $query
	 *
	 * @return $this
	 */
	protected function _buildQueryWhere(DatabaseQuery $query)
	{
		$config             = EDocmanHelper::getConfig();
		$db                 = $this->getDbo();
		$user               = Factory::getApplication()->getIdentity();
        $usergroup          = $user->groups;
        $usergroupArr       = [];
        $usergroupSql       = "";
        if(count($usergroup) > 0){
            foreach ($usergroup as $group){
                $usergroupArr[] = " `groups`='$group' OR `groups` LIKE '$group,%' OR `groups` LIKE '%,$group,%' OR `groups` LIKE '%,$group'";
            }
            $usergroupSql = implode(" OR ",$usergroupArr);
            $usergroupSql = " and tbl.id in (Select item_id from #__edocman_levels where `data_type` = '1' AND ( $usergroupSql )) ";
            //$usergroupSql = " OR ((tbl.user_ids = '' OR tbl.user_ids is NULL OR tbl.user_ids = 0) AND tbl.accesspicker = '1' AND $usergroupSql ) ";
        }

		$userId = $user->id;

		//Users with super admin permission should be able to see all documents
		if (!$user->authorise('core.admin', 'com_edocman'))
		{
			//update with Group IDs
			/**
			if($config->user_group_ids)
			{
				$groupQuery = EdocmanHelper::buildUserGroupQuery('tbl.owner_group_ids');
				$query->where('tbl.published=1')
					->where("(((tbl.user_ids = '' OR tbl.user_ids is NULL OR tbl.user_ids = 0) AND tbl.owner_group_ids = '' AND tbl.access IN (" . implode(',', $user->getAuthorisedViewLevels()) . ")) $usergroupSql ".$groupQuery." OR tbl.user_ids='$userId' OR tbl.user_ids LIKE '$userId,%' OR tbl.user_ids LIKE '%,$userId,%' OR tbl.user_ids LIKE '%,$userId' OR (tbl.created_user_id=$userId AND tbl.created_user_id > 0))");
			}
			else
			{
				$query->where('tbl.published=1')
					->where("(((tbl.user_ids = '' OR tbl.user_ids is NULL OR tbl.user_ids = 0) AND tbl.access IN (" . implode(',', $user->getAuthorisedViewLevels()) . ")) $usergroupSql OR tbl.user_ids='$userId' OR tbl.user_ids LIKE '$userId,%' OR tbl.user_ids LIKE '%,$userId,%' OR tbl.user_ids LIKE '%,$userId' OR (tbl.created_user_id=$userId AND tbl.created_user_id > 0))");
			}
			**/
			$whereConditions = [];
    
			// Trường hợp 1: owner_group_ids có giá trị - kiểm tra người dùng thuộc một trong các nhóm
			if ($config->user_group_ids) {
				// Xây dựng điều kiện kiểm tra owner_group_ids mà không sử dụng hàm buildUserGroupQuery
				$groups = $user->getAuthorisedGroups();
				$groupConditions = [];
				
				if (count($groups)) {
					foreach ($groups as $group) {
						$groupConditions[] = "tbl.owner_group_ids='$group' OR tbl.owner_group_ids LIKE '$group,%' OR tbl.owner_group_ids LIKE '%,$group,%' OR tbl.owner_group_ids LIKE '%,$group'";
					}
					
					if (!empty($groupConditions)) {
						$whereConditions[] = "(tbl.owner_group_ids != '' AND (" . implode(" OR ", $groupConditions) . "))";
					}
				}
			}
			
			// Trường hợp 2: user_ids có giá trị - kiểm tra ID người dùng hiện tại có trong danh sách
			$whereConditions[] = "(tbl.user_ids != '' AND tbl.user_ids IS NOT NULL AND tbl.user_ids != 0 AND (tbl.user_ids='$userId' OR tbl.user_ids LIKE '$userId,%' OR tbl.user_ids LIKE '%,$userId,%' OR tbl.user_ids LIKE '%,$userId'))";
			
			// Trường hợp 3: Cả owner_group_ids và user_ids đều rỗng - kiểm tra access
			$whereConditions[] = "((tbl.user_ids = '' OR tbl.user_ids IS NULL OR tbl.user_ids = 0) AND tbl.owner_group_ids = '' AND tbl.access IN (" . implode(',', $user->getAuthorisedViewLevels()) . "))";
			
			// Trường hợp 4: Cả owner_group_ids và user_ids đều rỗng - kiểm tra accesspicker
			if ($usergroupSql != "") {
				$whereConditions[] = "((tbl.user_ids = '' OR tbl.user_ids IS NULL OR tbl.user_ids = 0) AND tbl.owner_group_ids = '' ".$usergroupSql . ")";
			}
			
			// Trường hợp 5: Người tạo document là người dùng hiện tại
			$whereConditions[] = "(tbl.created_user_id=$userId AND tbl.created_user_id > 0)";
			
			// Kết hợp tất cả các điều kiện
			$query->where('tbl.published=1')
				  ->where("(" . implode(" OR ", $whereConditions) . ")");
		} 

		//$categoryId = $this->state->id ? $this->state->id : $this->state->filter_category_id;
		if ($this->state->filter_category_id)
		{
            $categoryId = $this->state->filter_category_id;
            $categoryIds = [];
            $categoryIds[] = $categoryId;
            $categoryIds = EDocmanHelper::getAllChildrenCategories($categoryIds);
            if($config->search_with_sub_cats) 
			{
                $query->where('tbl.id IN (SELECT document_id FROM #__edocman_document_category WHERE category_id IN(' . implode(',', $categoryIds) . '))');
            }
			else
			{
                $query->where('tbl.id IN (SELECT document_id FROM #__edocman_document_category WHERE category_id = ' . $categoryId . ' )');
            }
		}


		if($this->state->filter_created_user)
		{
		    $created_user = $this->filter->created_user;
		    if($created_user > 0)
			{
		        $query->where('tbl.created_user_id = "'.$created_user.'"');
            }
        }

        if($this->state->filter_related_documents == 1 && $this->state->document_id > 0)
		{
		    $query->where('tbl.id <> "'.$this->state->document_id.'"');
        }

        if($this->state->id > 0 && (int) $this->state->filter_category_id == 0 && $this->state->filter_tag == '' && $this->state->view != 'search')
		{
            $query->where('tbl.id IN (SELECT document_id FROM #__edocman_document_category WHERE category_id = ' . $this->state->id . ' )');
        }

		if ($this->state->filter_category_ids)
		{
			$categoryIds = explode(',', $this->state->filter_category_ids);
            ArrayHelper::toInteger($categoryIds);
			if ($this->includeChildrenCategory)
			{
				$categoryIds = EDocmanHelper::getAllChildrenCategories($categoryIds);
			}
			$query->where('tbl.id IN (SELECT document_id FROM #__edocman_document_category WHERE category_id IN(' . implode(',', $categoryIds) . '))');
		}

		if ($this->state->filter_categories_ids)
		{
			$categoryIds = explode(',', $this->state->filter_categories_ids);
            ArrayHelper::toInteger($categoryIds);
			$query->where('tbl.id IN (SELECT document_id FROM #__edocman_document_category WHERE category_id IN(' . implode(',', $categoryIds) . ') group by document_id having count(document_id) = "'.count($categoryIds).'")');
		}

		if ($this->state->exclude_category_ids)
		{
			$categoryIds = explode(',', $this->state->exclude_category_ids);
            ArrayHelper::toInteger($categoryIds);
			$query->where('tbl.id IN (SELECT document_id FROM #__edocman_document_category WHERE category_id NOT IN(' . implode(',', $categoryIds) . '))');
		}

		if ($this->state->filter_search)
		{
			if($config->save_what_user_search)
			{
				//prevent spam before saving filter search into database
				$startTime = Factory::getApplication()->getInput()->getInt(EdocmanHelper::getHashedFieldName(), 0);
				$session = Factory::getApplication()->getSession();

				$numberSubmissions = (int) $session->get('jd_number_submissions', 0) + 1;

				if ($numberSubmissions > (int) 20)
				{
					//do nothing
				}
				else
				{
					$session->set('jd_number_submissions', $numberSubmissions);
				}

				$filter_search_in_session = $session->get('filter_search_in_session','');
				if($filter_search_in_session != $this->state->filter_search)
				{
					$user_ip	= @$_SERVER['REMOTE_ADDR'];
					//$user_ip    = '58.186.216.234';
					$session->set('filter_search_in_session', $this->state->filter_search);
			
					$details    = json_decode(file_get_contents("http://ipinfo.io/".$user_ip."/json"));
					$city		= $details->city;
					$country	= $details->country;
					$postcode	= $details->postal;
					if(strlen($this->state->filter_search) >= 1)
					{
						$db->setQuery("Insert into  #__edocman_search_terms (id, keyword, searched_on , ip_address, city, postcode, country) values (NULL, '".$this->state->filter_search."', '".date('Y-m-d')."','$user_ip','$city', '$postcode', '$country')");
						$db->execute();
					}
				}
			}

			$query1 = "SHOW INDEX FROM `#__edocman_documents` 
					   WHERE Index_type = 'FULLTEXT' 
					   AND Column_name IN ('title', 'short_description', 'description')";
			$db->setQuery($query1);
			$indexes1 = $db->loadObjectList();
			$fullTextIndexExists = !empty($indexes1);


			$query2 = "SHOW INDEX FROM `#__edocman_documents` 
					   WHERE Index_type = 'FULLTEXT' 
					   AND Column_name = 'indexed_content'";
			$db->setQuery($query2);
			$indexes2 = $db->loadObjectList();
			$indexedContentFullTextExists = !empty($indexes2);

			if($fullTextIndexExists && $indexedContentFullTextExists)
			{
				$query->select("MATCH(tbl.title, tbl.description, tbl.short_description, tbl.indexed_content ) AGAINST (".$db->quote($this->state->filter_search)." IN BOOLEAN MODE) as sort_result");
				$query->where("(MATCH(tbl.title, tbl.description, tbl.short_description, tbl.indexed_content ) AGAINST (".$db->quote($this->state->filter_search)." IN BOOLEAN MODE))");
			}
			elseif($fullTextIndexExists && ! $indexedContentFullTextExists)
			{
				$matchCondition = "MATCH(tbl.title, tbl.description, tbl.short_description) AGAINST (".$db->quote($this->state->filter_search)." IN BOOLEAN MODE)";
    
				$keywords = explode(' ', $this->state->filter_search);
				$likeConditions = [];
				
				foreach ($keywords as $keyword) {
					if (strlen($keyword) >= 3) { 
						$likeConditions[] = "tbl.indexed_content LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%', false);
					}
				}
				
				$query->select("MATCH(tbl.title, tbl.description, tbl.short_description) AGAINST (".$db->quote($this->state->filter_search)." IN BOOLEAN MODE) as sort_result");
				
				if (count($likeConditions) > 0) {
					$likeClause = '(' . implode(' OR ', $likeConditions) . ')';
					$query->where("($matchCondition OR $likeClause)");
				} else {
					$query->where("($matchCondition)");
				}
			}
			else
			{
				$this->fallbackSearchMethod($query, $this->state->filter_search);
			}

			//for tag searching
			$search1 = strtolower(trim($this->state->filter_search));
			$subQuery = $db->getQuery(true);
			$subQuery->select('id')
				->from('#__edocman_tags')
				->where('LOWER(`tag`) LIKE ' . $db->quote('%' . $search1 . '%')); // Thêm % để tìm kiếm partial match
			$db->setQuery($subQuery);
			$tagId = (int) $db->loadResult();

			if($tagId > 0)
			{
				// Sử dụng extendWhere để thêm điều kiện OR một cách an toàn
				$query->extendWhere('OR', 'tbl.id IN (SELECT document_id FROM #__edocman_document_tags WHERE tag_id = ' . $tagId . ')');
			}

		}

		if ($this->state->filter_indicators)
		{
			switch ($this->state->filter_indicators)
			{
				case 'hot':
					$query->where(" tbl.indicators LIKE '%hot%' ");
				break;
				case 'featured':
					$query->where(" tbl.indicators LIKE '%featured%' ");
				break;
			}
		}

		if($this->state->filter_datetype)
		{
			switch($this->state->filter_datetype)
			{
				case "created":
					if($this->state->filter_startdate){
						$this->state->filter_startdate = strtolower(trim($this->state->filter_startdate));
						$query->where(" tbl.created_time >= '".$this->state->filter_startdate."'");
					}

					if($this->state->filter_enddate){
						$this->state->filter_enddate = strtolower(trim($this->state->filter_enddate));
						$query->where(" tbl.created_time <= '".$this->state->filter_enddate."'");
					}
				break;
				case "modified":
					if($this->state->filter_startdate){
						$this->state->filter_startdate = strtolower(trim($this->state->filter_startdate));
						$query->where(" tbl.modified_time >= '".$this->state->filter_startdate."'");
					}

					if($this->state->filter_enddate){
						$this->state->filter_enddate = strtolower(trim($this->state->filter_enddate));
						$query->where(" tbl.modified_time <= '".$this->state->filter_enddate."'");
					}
				break;
				case "publish":
					if($this->state->filter_startdate){
						$this->state->filter_startdate = strtolower(trim($this->state->filter_startdate));
						$query->where(" tbl.publish_up >= '".$this->state->filter_startdate."'");
					}

					if($this->state->filter_enddate){
						$this->state->filter_enddate = strtolower(trim($this->state->filter_enddate));
						$query->where(" tbl.publish_down <= '".$this->state->filter_enddate."'");
					}
				break;
			}
		}
		if ($this->state->filter_tag)
		{
			$tag      = strtolower(trim($this->state->filter_tag));
			$subQuery = $db->getQuery(true);
			$subQuery->select('id')
				->from('#__edocman_tags')
				->where('LOWER(`tag`) like ' . $db->quote($tag));
			$db->setQuery($subQuery);
			$tagId = (int) $db->loadResult();
			if($tagId > 0){
				$query->where(' tbl.id IN (SELECT document_id FROM #__edocman_document_tags WHERE tag_id=' . $tagId . ')');
			}
		}

		if (count($this->state->filter_tags) > 0)
        {
            $filterTags = $this->state->filter_tags;
            $query->where(' tbl.id IN (SELECT document_id FROM #__edocman_document_tags WHERE tag_id IN (' . implode(", ", $filterTags) . '))');
        }

		if($this->state->filter_filetype)
		{
			$filter_filetypes = $this->state->filter_filetype;
			$filter_filetypes = explode("-",$filter_filetypes);
			$tempSql = [];
			foreach($filter_filetypes  as $filetype){
				$tempSql[] = "(tbl.original_filename like '%.".$filetype."')";
			}
			$tempSql = "(".implode(" or ",$tempSql).")";
			$query->where($tempSql);
		}

		// Filter by start and end dates.
		if ((!$user->authorise('core.edit.state', 'com_edocman')) && (!$user->authorise('core.edit', 'com_edocman')))
		{
			$nullDate = $db->quote($db->getNullDate());
			$nowDate  = $db->quote(Factory::getDate()->toSql());
			$query->where('(tbl.publish_up = ' . $nullDate . ' OR tbl.publish_up <= ' . $nowDate . ')')
				->where('(tbl.publish_down = ' . $nullDate . ' OR tbl.publish_down >= ' . $nowDate . ')');
		}

		if ($config->activate_multilingual_feature && Factory::getApplication()->getLanguageFilter())
		{
			$query->where('tbl.language IN (' . $db->Quote(Factory::getLanguage()->getTag()) . ',' . $db->Quote('*') . ', "")');
		}
		//echo $query->__toString();die();
		return $this;
	}

	private function fulltextIndex($config, $db)
	{
		$dbName = $config->get('db');
		$query1 = $db->getQuery(true)
			->select($db->quoteName('index_name'))
			->from($db->quoteName('INFORMATION_SCHEMA.STATISTICS'))
			->where([
				$db->quoteName('table_schema') . ' = ' . $db->quote($dbName),
				$db->quoteName('table_name') . ' = ' . $db->quote('#__edocman_documents'),
				$db->quoteName('column_name') . ' = ' . $db->quote('indexed_content'),
				$db->quoteName('index_type') . ' = ' . $db->quote('FULLTEXT')
			]);
		
		$db->setQuery($query1);

		
	}


	private function indexedContentIndex($config, $db)
	{
		$db		= $this->getDbo();
		$dbName = $config->get('db');
		$query1 = $db->getQuery(true)
			->select($db->quoteName('index_name'))
			->from($db->quoteName('INFORMATION_SCHEMA.STATISTICS'))
			->where([
				$db->quoteName('table_schema') . ' = ' . $db->quote($dbName),
				$db->quoteName('table_name') . ' = ' . $db->quote('#__edocman_documents'),
				$db->quoteName('column_name') . ' = ' . $db->quote('indexed_content'),
				$db->quoteName('index_type') . ' = ' . $db->quote('FULLTEXT')
			]);
		
		$db->setQuery($query1);
		print_r($db->loadObjectList());die();
		//return !empty($db->loadResult());
	}

	private function fallbackSearchMethod($query, $searchTerm)
	{
		$keywords = explode(' ', $searchTerm);
		$db = $this->getDbo();

		// Điều kiện tìm kiếm và trọng số
		$searchConditions = [];
		$scoreConditions = [];

		foreach ($keywords as $keyword) {
			if (strlen($keyword) >= 3) {
				// Điều kiện LIKE cho từng trường
				$searchConditions[] = [
					'title' => "tbl.title LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%'),
					'short_description' => "tbl.short_description LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%'),
					'description' => "tbl.description LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%'),
					'indexed_content' => "tbl.indexed_content LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%')
				];

				// Tính điểm số theo thứ tự ưu tiên
				$scoreConditions[] = "(
					CASE 
						WHEN tbl.title LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%') . " THEN 40
						WHEN tbl.short_description LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%') . " THEN 30
						WHEN tbl.description LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%') . " THEN 20
						WHEN tbl.indexed_content LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%') . " THEN 10
						ELSE 0
					END
				)";
			}
		}

		// Xây dựng điều kiện WHERE
		$whereConditions = [];
		$scoreSelect = [];

		foreach ($searchConditions as $index => $conditions) {
			$subConditions = [];
			foreach ($conditions as $field => $condition) {
				$subConditions[] = $condition;
			}
			$whereConditions[] = '(' . implode(' OR ', $subConditions) . ')';
			$scoreSelect[] = $scoreConditions[$index];
		}

		// Ghép điều kiện
		if (!empty($whereConditions)) {
			$query->where('(' . implode(' AND ', $whereConditions) . ')');
			
			// Tính tổng điểm số
			$scoreSql = '(' . implode(' + ', $scoreSelect) . ') as search_score';
			$query->select($scoreSql);
			
			// Sắp xếp theo điểm số giảm dần
			$query->order('search_score DESC');
		}

		// Thêm điều kiện tìm kiếm toàn văn (fuzzy search)
		$this->addFuzzySearchCondition($query, $searchTerm);

		return $query;
	}

	private function addFuzzySearchCondition($query, $searchTerm)
	{
		$db = $this->getDbo();
		$keywords = explode(' ', $searchTerm);
		
		// Tính toán điểm số cho từng từ khóa
		$fuzzyScoreConditions = [];
		
		foreach ($keywords as $keyword) {
			if (strlen($keyword) >= 3) {
				$fuzzyScoreConditions[] = "(
					(CASE 
						WHEN tbl.title LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%') . " THEN 5
						ELSE 0
					END) +
					(CASE 
						WHEN tbl.short_description LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%') . " THEN 3
						ELSE 0
					END) +
					(CASE 
						WHEN tbl.description LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%') . " THEN 2
						ELSE 0
					END) +
					(CASE 
						WHEN tbl.indexed_content LIKE " . $db->quote('%' . $db->escape($keyword, true) . '%') . " THEN 1
						ELSE 0
					END)
				)";
			}
		}

		// Thêm điều kiện fuzzy search
		if (!empty($fuzzyScoreConditions)) {
			$fuzzySql = '(' . implode(' + ', $fuzzyScoreConditions) . ') as fuzzy_score';
			$query->select($fuzzySql);
			$query->order('fuzzy_score DESC');
		}

		return $query;
	}

    /**
     * Builds GROUP BY clause for the query
     *
     * @param JDatabaseQuery $query
     *
     * @return $this
     */
    protected function _buildQueryGroup(DatabaseQuery $query)
    {
        $query->group('tbl.id');
        return $this;
    }


	public function setIncludeChildren($includeChildrenCategory)
	{
		$this->includeChildrenCategory = $includeChildrenCategory;
	}

    /**
     * Builds a generic ORDER BY clause based on the model's state
     *
     * @param JDatabaseQuery $query
     *
     * @return $this
     */
    public function _buildQueryOrder(DatabaseQuery $query)
    {
		$db					= $this->getDbo();
        $sort      			= $this->state->filter_order;
		
		if($sort == "")
		{
			
		}
		$allowed_sort 		= array('tbl.title', 'tbl.created_time', 'tbl.modified_time', 'tbl.hits', 'tbl.id', 'tbl.ordering');
		if(!in_array($sort, $allowed_sort))
		{
			$sort = "tbl.created_time";	
		}
        $direction 			= strtoupper($this->state->filter_order_Dir);
		$allowed_direction 	= array('ASC','DESC');
		if(!in_array($direction, $allowed_direction))
		{
			$direction 		= "ASC";
		}
        if ($this->state->id) 
		{
            $categoryId     = $this->state->id;
            $category       = EDocmanHelper::getCategory($categoryId);
            $sort_option    = $category->sort_option;
            $sort_direction = $category->sort_direction;
            if($sort_option != "")
            {
                $sort       = $sort_option;
            }
            if($sort_direction != "")
            {
                $direction  = strtoupper($sort_direction);
            }
        }
		
		if($this->state->filter_search != "")
		{
			$query1 = "SHOW INDEX FROM `#__edocman_documents` 
					   WHERE Index_type = 'FULLTEXT' 
					   AND Column_name IN ('title', 'short_description', 'description')";
			$db->setQuery($query1);
			$indexes1 = $db->loadObjectList();
			$fullTextIndexExists = !empty($indexes1);

			if($fullTextIndexExists)
			{
				if ($sort)
				{
					$query->order('sort_result desc, '. $sort . ' ' . $direction . '');
				}
				else
				{
					$query->order(' sort_result desc');
				}
			}
			else
			{
				$query->order($sort . ' ' . $direction . '');
			}
		}
		else
		{
			$query->order($sort . ' ' . $direction . '');
		}
		//echo $query->__toString();die();

        return $this;
    }
}
