#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>


#include "../global.h"


#include "shared_strtrm.h"
#include "shared_authenticate.h"
#include "shared_cs_util.h"
#include "shared_cs_course_search.h"
#include "shared_server_string.h"
#include "shared_super_util.h"




void
cs_read_course_search_params( const char *username, COURSE_SEARCH_PARAMS *params)
{
 

  SUBDIR_NODE *node_ptr;
  char msg[80];
  char *str =0;
  HDF *obj;
  

  params->subdir_head = 0;
    
  cs_get_optional_parameter("type", msg, 10);   /* shared_cs_util.c */

  if(!strlen(msg))   /* type parameter wasn't sent - we need to use the last search criteria */
    {
     get_last_search_selections(username, params);
     if(!params->subdir_head)   /* no data found */
        cs_critical_error(ERR_PARAM_MISSING, "subdir");
    }
   else   /* the type parameter was there -get the rest from the cgi input */
    {      
      
     params->type = atoi(msg);

     cs_get_optional_parameter("search", params->search, MAX_FILENAME);   /* shared_cs_util.c */
     strtrm(params->search);

     cs_get_required_parameter("where", msg, 10);   /* shared_cs_util.c */
     params->where = atoi(msg);
 
     /* "subdir" is a multi selection list, parse the linked list directly */

     str = hdf_get_value(global_cgi->hdf, "Query.subdir.0", 0);
     if(str)   /* there are multi values */
     {
	   obj = hdf_get_child(global_cgi->hdf,"Query.subdir");
	   while(obj)
	   {
	       str = obj->value;
	       if(str && strlen(str))
	       {
                  if(!params->subdir_head)
		  {
                     params->subdir_head = (SUBDIR_NODE *) malloc(sizeof(SUBDIR_NODE));
                     if(!params->subdir_head)
                       cs_critical_error(ERR_MALLOC_FAILED, "");
                     node_ptr = params->subdir_head;
		  }
		  else
                  {
                     node_ptr->next = (SUBDIR_NODE *) malloc(sizeof(SUBDIR_NODE));
                     if(!node_ptr->next)
                         cs_critical_error(ERR_MALLOC_FAILED, "");
                     node_ptr = node_ptr->next;
                  } 
                   strncpy(node_ptr->subdir, str, MAX_COURSE_SUBDIR + 1);
                   *(node_ptr->subdir + MAX_COURSE_SUBDIR) = '\0';
                   strtrm(node_ptr->subdir);    /* shared_strtrm.c */
                   node_ptr->next = 0;

	       }
	       obj = obj->next;
	   }
        }      /* end multi values */
        else   /* single value */
        {
             str = hdf_get_value(global_cgi->hdf, "Query.subdir", 0);
	     if(str)
	     {
                  params->subdir_head = (SUBDIR_NODE *) malloc(sizeof(SUBDIR_NODE));
                  if(!params->subdir_head)
                       cs_critical_error(ERR_MALLOC_FAILED, "");
                  node_ptr = params->subdir_head;
                  strncpy(node_ptr->subdir, str, MAX_COURSE_SUBDIR + 1);
                  *(node_ptr->subdir + MAX_COURSE_SUBDIR) = '\0';
                  strtrm(node_ptr->subdir);    /* shared_strtrm.c */
                  node_ptr->next = 0;
	     }
       }	 
    if(!params->subdir_head)
      cs_critical_error(ERR_PARAM_MISSING, "subdir");
     
    write_last_search_selections(username, params); 
     
  }  /* else read from cgi input */
}      





void
cs_set_course_group_option_list(const char *course_path, const char *username)
{
 #define MAX_TMP_NAME 50

   GROUP_INFO_LIST *head, *ptr;
   int i =0;
   char name[MAX_TMP_NAME];
   COURSE_SEARCH_PARAMS last_search;
   
   last_search.subdir_head = 0;   
      
   head = build_group_list(course_path);    /* shared_course_search.c */
   if(*username)
       get_last_search_selections(username, &last_search);
   cs_set_value("course_group_new", "__new__");
   cs_set_value("course_group_all", "__all__");
   cs_set_value("course_group_templates", TEMPLATES_NAME);
   for(ptr = head, i = 0; ptr; ptr = ptr->next, i++)
   {
      snprintf(name, MAX_TMP_NAME, "course_group.%d.value", i);
      cs_set_value(name, ptr->subdir);
      snprintf(name, MAX_TMP_NAME, "course_group.%d.description", i);
      cs_set_value(name, ptr->short_description);
      if(*username && in_last_search(ptr->subdir, &last_search))
       {
        snprintf(name, MAX_TMP_NAME, "course_group.%d.is_selected", i);
        cs_set_int_value(name, 1);
       }
      
   }
      
  free_course_group_list(head);
  if(*username)
      free_subdir_list(last_search.subdir_head);
#undef MAX_TMP_NAME
}









	   
void cs_set_search_criteria (COURSE_SEARCH_PARAMS *params, COURSE_SEARCH_NODE *course_head, 
								const char *key, const char *prog)
{
#define MAX_TMP_NAME 50

 SUBDIR_NODE *ptr;
 COURSE_SEARCH_NODE *course_ptr;
 char short_description[MAX_SEMESTER + 1];
 int matches;
 int j =0, i=0;
 char name[MAX_TMP_NAME];
 char url[MAX_PATH +1];
 char server_name[MAX_PATH +1];

 get_server_string(server_name, MAX_PATH);
    for(course_ptr=course_head, matches=0; course_ptr; course_ptr=course_ptr->next)
                 matches++;
    cs_set_int_value("number_matches", matches);              
    cs_set_value("search_param", params->search);              

    for(ptr= params->subdir_head; ptr; ptr=ptr->next)
     {
      if(strcmp(ptr->subdir, TEMPLATES_NAME))
       {
        get_short_group_description(ptr->subdir, short_description);
        snprintf(name, MAX_TMP_NAME, "subdir.%d.value", i);
        cs_set_value(name, ptr->subdir);
        snprintf(name, MAX_TMP_NAME, "subdir.%d.desc", i);
        cs_set_value(name, short_description);
        if(strlen(prog))   /* then link short description to the "super_group_description" program */
         {
           snprintf(name, MAX_TMP_NAME, "subdir.%d.url", i);
           snprintf(url, MAX_PATH +1,  "%s/%s/%s?id=%s&amp;subdir=%s&amp;from=%s",server_name, SBIN_ALIAS,"super_group_description",key,ptr->subdir,prog);
	   cs_set_value(name, url);
         } 
         i++;
       }  /* if this isn't a __templates__ */ 
      else
      {
         snprintf(name, MAX_TMP_NAME, "temp.%d", j);
	 cs_set_int_value(name, 1);
	 j++;
      }
     }

    cs_set_int_value("params_type", params->type);
    cs_set_int_value("params_where", params->where);
#undef MAX_TMP_NAME

}



void
cs_set_search_form( char *action,  char *key, const char *username)
{
  if(strlen(action))
     cs_set_value("action", action);
  if(strlen(key)) 
     cs_set_value("key", key);
   
   cs_set_int_value("max_search", MAX_FILENAME);
   cs_set_course_group_option_list(COURSE_PATH, username);  
}   






static void
cs_set_subdir_info( int num, COURSE_SEARCH_NODE *ptr, const char *prog,  const char *key, int kind, int id)
{
#define MAX_TMP_NAME 50

     char subdir_description[MAX_SUBJECT + 1];
     char *esc_subdir_description = 0;
     char name[MAX_TMP_NAME];
     char url[MAX_PATH +1];
     char node_str[MAX_PATH*2 +1];
     char server_name[MAX_PATH +1];
     char *str =0;
     
     get_server_string(server_name, MAX_PATH);
     get_short_group_description(ptr->subdir, subdir_description); /* shared_cs_course_search.c */
     
     
     *url = '\0';

    if(strlen(subdir_description) == 0)
     {
      /* caller program must load lang */
      str = hdf_get_value(global_cgi->hdf, "lang.super_course_search.no_description", 0); 
      if(str && strlen(str))
	  strncpy(subdir_description, str, MAX_SUBJECT +1);
     }
     
    cgi_js_escape(subdir_description, &esc_subdir_description); 
    
    str = hdf_get_value(global_cgi->hdf, "lang.super_course_search.desc_help", 0); 
   
    if(strlen(prog))
     {

      snprintf(url, MAX_PATH +1,  "%s/%s/%s?id=%s&amp;subdir=%s&amp;from=%s", 
			server_name, SBIN_ALIAS, "super_group_description",key,ptr->subdir,prog);
     }
    

    if(strlen(url))
     snprintf(node_str, MAX_PATH * 2 + 1, "%d, %d, '%s (%s)', '%s', '%s' ", 
			id, kind, ptr->subdir, esc_subdir_description,  url, str ? str: "");
    else
     snprintf(node_str, MAX_PATH * 2 + 1, "%d, %d, '%s (%s)'", 
			id, kind, ptr->subdir, esc_subdir_description);

    
    snprintf(name, MAX_TMP_NAME, "node.%d",  num);
    cs_set_value(name, node_str);


  if(esc_subdir_description)
      free(esc_subdir_description);
      
 #undef MAX_TMP_NAME
}






static void
cs_set_course_letter(int number_nodes, char course_letter, int id, int parent_id)
{
    #define MAX_TMP_NAME 50

   char node_str[MAX_PATH +1];
   char name[MAX_TMP_NAME];
   
   snprintf(name, MAX_TMP_NAME, "node.%d",  number_nodes);
   snprintf(node_str, MAX_PATH +1,  "%d, %d, '%c'", id, parent_id, course_letter);
   cs_set_value(name, node_str);

 #undef MAX_TMP_NAME
}






static void
cs_set_matched_course_info(int number_nodes, COURSE_SEARCH_NODE *ptr, const char *key, int id, int parent_id, const char *prog)
{
    #define MAX_TMP_NAME 50
   char name[MAX_TMP_NAME];
   char url[MAX_PATH +1];
   char node_str[MAX_PATH *2 +1];
   char server_name[MAX_PATH +1];
   char *str =0;
   
   char *esc_course_no = 0,
        *esc_title = 0,
        *esc_semester = 0,
        *esc_instructor = 0;
        
        
   cgi_js_escape(ptr->conf.course_no,&esc_course_no);
   cgi_js_escape(ptr->conf.title,&esc_title);
   cgi_js_escape(ptr->conf.semester,&esc_semester);
   cgi_js_escape(ptr->conf.instructor,&esc_instructor);
     

   get_server_string(server_name, MAX_PATH);
   cs_set_value("server_name", server_name);
   cs_set_value("sbin_alias", SBIN_ALIAS);
   
   if( !strcmp(prog, "super_archive_courses"))
   {
	
    snprintf(url, MAX_PATH +1, "%s?id=%s&amp;course=%s/%s", 
		    "super_download_tar", key, ptr->subdir, ptr->dirname);
    snprintf(node_str, (MAX_PATH * 2) + 1, "%d, %d, '%s %s %s %s (%s/%s)', '%s'", 
                             id, parent_id, esc_course_no, esc_title, 
                             esc_semester, esc_instructor, 
		             ptr->subdir, ptr->dirname, url);
   }
   else if( !strcmp(prog, "super_config_course_list")) 
   {
    str = hdf_get_value(global_cgi->hdf, "lang.super_course_search.enter", 0); 
    snprintf(url, MAX_PATH +1, "%s/%s/%s?id=%s&amp;crs=%s/%s", 
		    server_name, SBIN_ALIAS, "super_config_course", key, ptr->subdir, ptr->dirname);

    snprintf(node_str, MAX_PATH *2 +1, "%d, %d, '%s %s %s %s (%s/%s)', '%s', '%s %s'", 
		    id, parent_id, esc_course_no, esc_title, esc_semester, esc_instructor, 
		    ptr->subdir, ptr->dirname, url, str? str:"", esc_title);
   }
   else if( !strcmp(prog, "super_change_course_access_form")) 
   {
     snprintf(name, MAX_TMP_NAME, "lang.super_course_search.access.%d.msg",  ptr->conf.access);
     str = hdf_get_value(global_cgi->hdf, name, 0); 
     snprintf(url, MAX_PATH +1, 
		    "<input type=\"checkbox\" class=\"chbox\" name=\"crs\" value=\"%s/%s\" title=\"%s\"/>",
		    ptr->subdir, ptr->dirname, esc_title); 
		     
    snprintf(node_str, MAX_PATH *2 +1, "%d, %d, '%s %s %s %s (%s/%s) %s'", 
		    id, parent_id, url, esc_course_no,  esc_semester, esc_instructor, 
		    ptr->subdir, ptr->dirname, str ? str:"");
     
   }
   else if( !strcmp(prog, "super_archive_course_form")) 
   {
    str = hdf_get_value(global_cgi->hdf, "lang.super_course_search.download_tar", 0);
    snprintf(url, MAX_PATH +1, "%s/%s/%s?id=%s&amp;course=%s/%s", 
		    server_name, SBIN_ALIAS, "super_download_tar", key, ptr->subdir, ptr->dirname);

    snprintf(node_str, MAX_PATH *2 +1, "%d, %d, '%s %s %s (%s/%s)  %s', '%s', '%s--%s'", 
		    id, parent_id, esc_course_no, esc_semester, esc_instructor, 
		    ptr->subdir, ptr->dirname, str? str:"", url, str? str:"", esc_title);
    

   }
   else if( !strcmp(prog, "super_delete_course_form") || !strlen(prog)) 
   {
    snprintf(url, MAX_PATH +1, 
		    "<input type=\"checkbox\" class=\"chbox\" name=\"course_list\" value=\"%s/%s:%s %s %s %s\" />",
		    ptr->subdir, ptr->dirname, esc_course_no, esc_title, 
		    esc_semester, esc_instructor); 
    snprintf(node_str, MAX_PATH *2 +1, "%d, %d, '%s %s %s %s %s (%s/%s)'", 
		    id, parent_id, url, esc_course_no, esc_title, esc_semester, esc_instructor, 
		    ptr->subdir, ptr->dirname);
   } 
   else if( !strcmp(prog, "super_purge_postoffice_message_form")) 
   {
    snprintf(url, MAX_PATH +1, 
		    "<input type=\"checkbox\" class=\"chbox\" name=\"course_list\" value=\"%s/%s:%s %s %s %s\" />",
		    ptr->subdir, ptr->dirname, esc_course_no, esc_title, 
		    esc_semester, esc_instructor); 
    snprintf(node_str, MAX_PATH *2 +1, "%d, %d, '%s %s %s %s %s (%s/%s)'", 
		    id, parent_id, url, esc_course_no, esc_title, esc_semester, esc_instructor, 
		    ptr->subdir, ptr->dirname);
     
   }
  snprintf(name, MAX_TMP_NAME, "node.%d",  number_nodes);
  cs_set_value(name, node_str); 

  if(esc_course_no) 
      free(esc_course_no);

  if(esc_title) 
      free (esc_title);

  if(esc_semester)
       free (esc_semester);

  if(esc_instructor)
        free(esc_instructor);

    
 #undef MAX_TMP_NAME

}	





/* 'kind' parameter indicates the type of course to process
 * **  0 - normal, centralized courses
 * **  1 - standalone courses
 * **  2 - course templates
 * **/

static  void
set_matched_courses(COURSE_SEARCH_NODE *head, int kind, const char *prog, 
                            const char *key, int start_id, int *number_node)
{
#define MAX_TMP_NAME 50
 COURSE_SEARCH_NODE *ptr;
 char last_subdir[MAX_COURSE_SUBDIR + 1];
 char last_dir_letter;
 char course_letter;
 int letter_id = 1000 + start_id;
 int subdir_id =  start_id;
 int course_id = 10000 + start_id ;

 last_dir_letter = '\0';
 *last_subdir = '\0';


  if(head)
   {
       for(ptr = head; ptr; ptr = ptr->next)
       {
          if( ((kind == 0) && (!ptr->conf.template) && (!ptr->conf.standalone) )  ||
		((kind == 1) && (!ptr->conf.template) && (ptr->conf.standalone)  )  ||
		  ((kind == 2) && (ptr->conf.template) ) )
          {
              if(strcmp(ptr->subdir, last_subdir))  /* new group */
	      {
                  cs_set_subdir_info( *number_node, ptr, prog, key, kind + 1, subdir_id);
		  strncpy(last_subdir, ptr->subdir, MAX_COURSE_SUBDIR + 1);
                  last_dir_letter = '\0';
		  (*number_node)++;
		  subdir_id++;
	      }

	      course_letter = *(ptr->dirname);
              if(course_letter != last_dir_letter)
	      {
                   cs_set_course_letter( *number_node,  course_letter, letter_id, subdir_id -1);
                   last_dir_letter = course_letter;
	           (*number_node)++;
		   letter_id++;
	      }
              cs_set_matched_course_info( *number_node, ptr, key, course_id, letter_id -1, prog);
	      course_id ++;
	      (*number_node)++;
	  }
       }
   }
#undef MAX_TMP_NAME 
}



 
COURSE_SEARCH_NODE *read_search_course_parameters (char *key, COURSE_SEARCH_PARAMS *params)
{
 SESSION user;
 COURSE_SEARCH_NODE *course_head;   /* shared_course_search.h */
 
  
   cs_get_required_parameter ("id", key, MAX_KEY);   /* shared_cgi_util.c */
   cs_set_value("id", key);
   validate_super_key(key, &user);   /*shared_super_util.h */
   
   cs_read_course_search_params( user.username, params); /* shared_cs_course_search.c */
   course_head = build_course_search_list(params); /* shared_cs_course_search.c */
   return course_head;
   
   
}  


void
cs_set_searched_courses( const char *key, COURSE_SEARCH_NODE *course_head, COURSE_SEARCH_PARAMS *params, const char *prog)
{
	
  COURSE_SEARCH_NODE *course_ptr;
              
  int normal_count = 0,
      standalone_count = 0,
      template_count = 0;
  int number_nodes = 0;
      

       
 for(course_ptr=course_head; course_ptr; course_ptr=course_ptr->next)
 {
  if(course_ptr->conf.template)
      template_count++;
  else if(course_ptr->conf.standalone == 1)
       standalone_count++;
  else
       normal_count++;   
 }

  cs_load_lang("super_course_search");

  if(template_count)
  {
     cs_set_int_value("temp_count", template_count);
     set_matched_courses(course_head,  2, prog, key, 10, &number_nodes);
  }
  if(standalone_count >0)
  {
     cs_set_int_value("std_count", standalone_count);
     set_matched_courses(course_head,  1, prog, key,  100, &number_nodes);
  }
  if(normal_count)
  {
     cs_set_int_value("normal_count", normal_count);
     set_matched_courses(course_head,   0, prog, key, 1000, &number_nodes);
  }
  cs_set_search_criteria (params, course_head, key, prog);   /* shared_course_search.c */
}



