//
// The line above should be left blank to avoid script errors in OpenSim.
// LSL script generated: mod.set-1.0.rezzer_reset_btn.lslp Tue Nov 15 15:49:28 Tokyo Standard Time 2011
/*
*  Part of the Sloodle project (www.sloodle.org)
*
*  Copyright (c) 2011-06 contributors (see below)
*  Released under the GNU GPL v3
*  -------------------------------------------
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see .
*
*  All scripts must maintain this copyrite information, including the contributer information listed
*
*  Contributors:
*  Paul Preibisch
*
*  DESCRIPTION
*  Rezzer.lslp
*  This script is responsible for:
*  *** initiating the loading of a quiz
*  *** getting the first question and loading the options as texture maps on the child prims (pie_slices)
*  *** initiating a countdown in the timer.lslp script
*  *** starting a sensor, and using hovertext to display which pie_slice a user is standing over
*  *** determining the value of each option and telling each pie_slice to open or close when the count down timer reaches zero 
*  *** determining which pie_slice a user is standing over at the end of the countdown, and submitting their answers to the notify_server.lslp script 
*  *** rezzing orbs on each of its edges which are clickable by avatars who answered correctly 
*  *** receive linked messages from the orbs which indicate touch events from avatars who have answered the question correctly, and rez 
*      rezzing child hexagons along the touched edges 
*  *** Receive GET QUESTION command from a child hex when its center orb has been touched by an avatar
*  *** requesting questions from question_handler.lslp and passing retrieved question along to the requesting child hexagon
*      
*
*/
float edge_length;
list QUESTIONS_ASKED;
float edge_length_half;
string CONFIG;
float tip_to_edge;
list rezzed_hexes;
list opids;
integer PIN=7961;
integer doRepeat;
integer doRandomize;
integer doPlaySound;
integer quiz_id;
string quiz_name;
integer question_id;
list question_ids;
integer num_questions;
integer current_question;
string sloodleserverroot = "";
integer sloodlecontrollerid = 0;
string sloodlepwd = "";
integer sloodlemoduleid = 0;
integer sloodleobjectaccessleveluse = 0; // Who can use this object?
integer sloodleobjectaccesslevelctrl = 0; // Who can control this object?
integer sloodleserveraccesslevel = 0; // Who can use the server resource? (Value passed straight back to Moodle)
integer isconfigured = FALSE; // Do we have all the configuration data we need?
integer eof = FALSE; // Have we reached the end of the configuration data?
string SLOODLE_EOF = "sloodleeof";
string sloodle_quiz_url = "/mod/sloodle/mod/quiz-1.0/linker.php";
list  sides_rezzed;
string QUIZ_DATA;
integer TIME_LIMIT;
list GRAND_CHILDREN;
integer SLOODLE_REMOTE_LOAD_SCRIPT=1639277018;
string HEX_CONFIG_SEPARATOR="*^*^*^";
integer SLOODLE_CHANNEL_ANIM= -1639277007;
integer SLOODLE_CHANNEL_OBJECT_DIALOG = -3857343; // an arbitrary channel the sloodle scripts will use to talk to each other. Doesn't atter what it is, as long as the same thing is set in the sloodle_slave script. 
integer SLOODLE_CHANNEL_ANSWER_SCORE_FOR_AVATAR = -1639271113; // Tells anyone who might be interested that we scored the answer. Score in string, avatar in key.
integer SLOODLE_SET_TEXTURE= -1639277010; 
integer SLOODLE_CHANNEL_QUIZ_MASTER_RESPONSE= -1639277008;
integer SLOODLE_CHANNEL_QUIZ_MASTER_REQUEST= -1639277006;
integer SLOODLE_CHANNEL_USER_TOUCH = -1639277002;//user touched object
integer SLOODLE_CHANNEL_QUIZ_LOADING_QUIZ = -1639271109;
string SLOODLE_TRANSLATE_HOVER_TEXT = "hovertext";          // 2 output parameters: colour , and alpha value
string SLOODLE_TRANSLATE_WHISPER = "whisper";               // 1 output parameter: chat channel number
string SLOODLE_TRANSLATE_SAY = "say";               // 1 output parameter: chat channel number
string SLOODLE_TRANSLATE_OWNER_SAY = "ownersay";    // No output parameters
string SLOODLE_TRANSLATE_DIALOG = "dialog";         // Recipient avatar should be identified in link message keyval. At least 2 output parameters: first the channel number for the dialog, and then 1 to 12 button label strings.
string SLOODLE_TRANSLATE_LOAD_URL = "loadurl";      // Recipient avatar should be identified in link message keyval. 1 output parameter giving URL to load.
string SLOODLE_TRANSLATE_IM = "instantmessage";     // Recipient avatar should be identified in link message keyval. No output parameters.
integer SLOODLE_CHANNEL_TRANSLATION_REQUEST = -1928374651;
integer SLOODLE_CHANNEL_QUIZ_ASK_QUESTION = -1639271112; //used when this script wants to ask a question and have the results sent to the child hex
integer SLOODLE_CHANNEL_QUESTION_ASKED_AVATAR = -1639271105; //Sent by main quiz script to tell UI scripts that question has been asked to avatar with key. String contains question ID + "|" + question text
integer SLOODLE_CHANNEL_QUIZ_LOADED_QUIZ = -1639271110;
integer SLOODLE_CHANNEL_QUIZ_NOTIFY_SERVER_OF_RESPONSE= -1639277004;
integer SLOODLE_CHANNEL_QUIZ_STATE_ENTRY_LOAD_QUIZ_FOR_USER = -1639271116; //mod quiz script is in state CHECK_QUIZ
integer SLOODLE_TRANSLATE_HOVER_TEXT_LINKED_PRIM= -1639277009; // 3 output parameters: colour ,  alpha value, link number
string HEXAGON_PLATFORM="Hexagon Platform";
integer TIMES_UP=FALSE;
integer num_options=0;
list CORRECT_AVATARS;
list options;//store pie slice correlation. Therefore option[0]=pie_slice# 
integer quiz_loaded=FALSE;
vector RED =<1.00000, 0.00000, 0.00000>;
vector ORANGE=<1.00000, 0.43763, 0.02414>;
vector YELLOW=<1.00000, 1.00000, 0.00000>;
vector GREEN=<0.00000, 1.00000, 0.00000>;
vector BLUE=<0.00000, 0.00000, 1.00000>;
vector BABYBLUE=<0.00000, 1.00000, 1.00000>; 
vector PINK=<1.00000, 0.00000, 1.00000>;
vector PURPLE=<0.57338, 0.25486, 1.00000>;
vector BLACK= <0.00000, 0.00000, 0.00000>;
vector WHITE= <1.00000, 1.00000, 1.00000>;
vector AVCLASSBLUE= <0.06274,0.247058,0.35294>;
vector AVCLASSLIGHTBLUG=<0.8549,0.9372,0.9686>;//#daeff7
integer SLOODLE_TIMER_START= -1639277011; //shoudl be used to starts the timer from its current position
integer SLOODLE_TIMER_RESTART= -1639277012;//should be used to set the counter to 0 and begin counting down again
integer SLOODLE_TIMER_STOP= -1639277013;//should stop the timer at its current position
integer SLOODLE_TIMER_STOP_AND_RESET= -1639277014;//should stop the timer at its current position and reset count to 0
integer SLOODLE_TIMER_RESET= -1639277015;//shoudl reset the count back to zero but not restart the timer
integer SLOODLE_TIMER_TIMES_UP= -1639277016;//used to transmit the timer reached its time limit
list MY_SLICES;
integer already_received_question=FALSE;
integer my_start_param;
list pie_slice_hover_text;
string qdialogtext;
list qdialogoptions;
list option_points;
debug (string message ){
     list params = llGetPrimitiveParams ([PRIM_MATERIAL ]);
     if (llList2Integer (params ,0)==PRIM_MATERIAL_FLESH){
           llOwnerSay("memory: "+(string)llGetFreeMemory()+" Script name: "+llGetScriptName ()+": " +message );
     }
} 
//rezzes a hexagon at the indicated orb#
rez_hexagon(integer orb){
    if (llGetListLength(QUESTIONS_ASKED)>=num_questions){
        //quiz finished
        sloodle_translation_request(SLOODLE_TRANSLATE_SAY, [0], "no_more_questions", [], NULL_KEY, "hex_quizzer");
        return;
     }
     integer my_oposite_section;
     vector my_coord= llGetPos();
     if (orb==0){
         return;
     }
     float adjustment_x = 0.0402;
     float adjustment_y = -0.0365;
     vector child_coord=my_coord;
     integer DIVISER=1;
     if (orb==1){//yellow
        child_coord.x=my_coord.x + edge_length + edge_length/2;
        child_coord.y=my_coord.y -tip_to_edge;  
        my_oposite_section=4;                              
     }else
     if (orb==2){//pink
        child_coord.x=my_coord.x;
        child_coord.y=my_coord.y-tip_to_edge * 2;  
        my_oposite_section=5;
     }else
     if (orb==3){
        child_coord.x=my_coord.x - edge_length- edge_length/2;
        child_coord.y=my_coord.y - tip_to_edge; 
        my_oposite_section=6;
     }else
     if (orb==4){
        child_coord.y=my_coord.y+tip_to_edge;   
        child_coord.x=my_coord.x-edge_length-edge_length/2;
        my_oposite_section=1;
     }else 
     if (orb==5){
        child_coord.x=my_coord.x;
        child_coord.y=my_coord.y+ tip_to_edge * 2; 
        my_oposite_section=2;
     }else
     if (orb==6){
        child_coord.x=my_coord.x+ edge_length+edge_length/2;
        child_coord.y=my_coord.y+tip_to_edge; 
        my_oposite_section=3;
     }
    // child_coord.x=child_coord.x+ adjustment_x;
    // child_coord.y=child_coord.y+ adjustment_y;
    //rez a new hexagon, and pass my_oppsosite_section as the start_parameter so that the new hexagon wont rez on that the my_oposite_section edge
    llRezAtRoot(HEXAGON_PLATFORM, child_coord, ZERO_VECTOR,  llGetRot(), my_oposite_section);
}
set_all_pie_slice_hover_text(string msg){
    pie_slice_hover_text=[];
    pie_slice_hover_text+=" ";
    integer pie_slice_num;
     for (pie_slice_num=1;pie_slice_num<=6;pie_slice_num++){
         sloodle_translation_request("SLOODLE_TRANSLATE_HOVER_TEXT_LINKED_PRIM", [ORANGE, 1.0,get_prim("option"+(string)pie_slice_num)], "option", [msg], "", "hex_quizzer");
         pie_slice_hover_text+=msg;
     }
}
//returns the pie_slice the avatar is standing near
string get_detected_pie_slice(vector avatar){
    //returns name of pie_slice
    integer i;
    float closest_orb_distance=100.0;
    string  name_of_closest_orb="";
    integer closest_orb_link_number;
    integer root_orb= get_prim("Hexagon Quizzer");
    for (i=1;i<=6;i++){
        integer orb_link_number = get_prim("orb"+(string)i);
        list orb_data=llGetLinkPrimitiveParams(orb_link_number, [PRIM_POSITION]);
        
        vector orb_pos = llList2Vector(orb_data, 0);
        float detected_distance_from_avatar_to_orb = llVecDist(orb_pos, avatar);
        if (detected_distance_from_avatar_to_orb 1) value1 = llList2String(bits,1);
            if (numbits > 2) value2 = llList2String(bits,2);
            if (name == "set:sloodleserverroot") sloodleserverroot = value1;
            else if (name == "set:sloodlepwd") {
                // The password may be a single prim password, or a UUID and a password
                if (value2 != "") {
                   sloodlepwd = value1 + "|" + value2;
                }
                else {
                    sloodlepwd = value1;
                }
            }
            else if (name == "set:questiontimelimit"){
            	 TIME_LIMIT= (integer)value1;
            	   debug("\n\n\n\n\n we got time limit is: "+(string)TIME_LIMIT);
            }
            else if (name == "set:sloodlecontrollerid") sloodlecontrollerid = (integer)value1;
            else if (name == "set:sloodlemoduleid") sloodlemoduleid = (integer)value1;
            else if (name == "set:sloodleobjectaccessleveluse") sloodleobjectaccessleveluse = (integer)value1;
            else if (name == "set:sloodleserveraccesslevel") sloodleserveraccesslevel = (integer)value1;
            else if (name == "set:sloodlerepeat") doRepeat = (integer)value1;
            else if (name == "set:sloodlerandomize") doRandomize = (integer)value1;
            else if (name == "set:sloodleplaysound") doPlaySound = (integer)value1;
            else if (name == SLOODLE_EOF) eof = TRUE;
            return (sloodleserverroot != "" && sloodlepwd != "" && sloodlecontrollerid > 0 && sloodlemoduleid > 0);
       }
default {
    on_rez(integer start_param){
        llResetScript();
    }
    state_entry() {
        integer n=llGetNumberOfPrims();
        integer j=0;
        for (j=0;j0){
                    //avatar is correct
                    if (llListFindList(CORRECT_AVATARS, [avatar_name])==-1){ //dont add same name twice
                        sloodle_translation_request(SLOODLE_TRANSLATE_IM, [0], "correct_select_orb", [avatar_name], avatar_key, "hex_quizzer");
                        CORRECT_AVATARS+=avatar_key;//record which avatars are correct because only those who are correct can click an orb
                        llMessageLinked(LINK_SET, SLOODLE_CHANNEL_QUIZ_NOTIFY_SERVER_OF_RESPONSE,"multichoice|"+(string)question_id+"|"+(string)opid+"|"+(string)score_change, avatar_key);
                        llMessageLinked(LINK_SET, SLOODLE_CHANNEL_ANSWER_SCORE_FOR_AVATAR, (string)score_change+"|"+(string)llGetKey(), avatar_key);
                    }
                    
                }else{
                     llMessageLinked(LINK_SET, SLOODLE_CHANNEL_QUIZ_NOTIFY_SERVER_OF_RESPONSE,"multichoice|"+(string)question_id+"|"+(string)opid+"|"+(string)score_change, avatar_key);
                    sloodle_translation_request(SLOODLE_TRANSLATE_IM, [0], "incorrect_can_not_select_orb", [avatar_name], avatar_key, "hex_quizzer");
                    llPushObject(avatar_key,<0,0,100>, <0,0,-100>, TRUE);
                }
                
                string pie_slice_text =llList2String(pie_slice_hover_text,pie_slice_num);
                pie_slice_hover_text= llListReplaceList(pie_slice_hover_text, [pie_slice_text+"\n"+avatar_name], pie_slice_num, pie_slice_num);
                llMessageLinked(LINK_SET, SLOODLE_CHANNEL_ANIM, "orb show|0,1,2,3,4,5,6|10", NULL_KEY);
                integer j;
                string correct_avatars_str= "Avatars allowed to click:"+strReplace(llList2CSV(CORRECT_AVATARS),",","\n");
               
                for(j=1;j<=6;j++){
                    sloodle_translation_request("SLOODLE_TRANSLATE_HOVER_TEXT_LINKED_PRIM", [GREEN, 1.0,get_prim("orb")+(string)j], "option", [correct_avatars_str], "", "hex_quizzer");
                } 
                //check if this was the last question
                
                
            }
            //print names on pie slice hover text in GREEN if correct, in RED if incorrect
            string avatar_names;
            list grades=[];//retrieve the grade for each pie_slice
            vector color;
            for (pie_slice_num=1;pie_slice_num<=6;pie_slice_num++){
                     if (pie_slice_value(pie_slice_num)>0) {
                         color=GREEN;
                     }else{
                         color=RED;
                     }
                    avatar_names=llList2String(pie_slice_hover_text,pie_slice_num);
                    sloodle_translation_request("SLOODLE_TRANSLATE_HOVER_TEXT_LINKED_PRIM", [color, 1.0,get_prim("option"+(string)pie_slice_num)], "option", [avatar_names], "", "hex_quizzer");
                    integer grade = pie_slice_value(pie_slice_num);
                    grades+=grade;
            }
            //send the list of grades to the pie_slices so that they open or close.  If grade is 0 for that option, pie_slice will open
            llMessageLinked(LINK_SET, SLOODLE_CHANNEL_ANIM, "pie_slice|"+llList2CSV(grades), NULL_KEY);
            
            debug("sending grades to pie_slices: "+llList2CSV(grades));         
    
        };
    }
    object_rez(key platform) {
        //a new hex was rezzed, listen to the new hex platform
            llListen(SLOODLE_CHANNEL_QUIZ_MASTER_REQUEST, "", platform, "");
            rezzed_hexes+=platform;
            llGiveInventory(platform, HEXAGON_PLATFORM);
            debug("giving platform script");
            //since llRemoteLoadScriptPin makes a script sleep for 3 seconds, we need to offload the remote loading of the scripts to a seperate loader script
   /*         llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "0|"+(string)PIN+"|sloodle_translation_en.lslp|"+(string)TRUE+"|0", platform);
            llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "1|"+(string)PIN+"|sloodle_translation_hex_quizzer_en.lslp|"+(string)TRUE+"|0", platform);
            llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "2|"+(string)PIN+"|timer.lslp|"+(string)TRUE+"|0", platform);
            llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "3|"+(string)PIN+"|delayed_set_text.lslp|"+(string)TRUE+"|0", platform);
            llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "4|"+(string)PIN+"|feedback_request.lslp|"+(string)TRUE+"|0", platform);
            llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "5|"+(string)PIN+"|finish_quiz.lslp|"+(string)TRUE+"|0", platform);
            llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "6|"+(string)PIN+"|load_quiz.lslp|"+(string)TRUE+"|0", platform);
            llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "7|"+(string)PIN+"|notify_server_of_response.lslp|"+(string)TRUE+"|0", platform);
            llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "8|"+(string)PIN+"|sloodle_quiz_question_handler.lslp|"+(string)TRUE+"|0", platform);
            llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "9|"+(string)PIN+"|hex_multi_user_quiz.lslp|"+(string)TRUE+"|0", platform);
            llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "10|"+(string)PIN+"|rezzer_platform.lslp|"+(string)TRUE+"|0", platform);
            */
            llRemoteLoadScriptPin(platform, "rezzer_platform.lslp",PIN, TRUE, 0);
            
           
    }
    listen(integer channel, string name, key id, string message) {
        list data = llParseString2List(message, ["|"], []);
        string command = llList2String(data, 0);
        debug("************************** command is: "+command);
        if (command=="rezzed grandchild"){
	       	debug("a grandchild.. i hope its mine!");
	       	string my_hash =  llSHA1String(sloodleserverroot+sloodlecontrollerid+sloodlemoduleid);
	        string received_hash=llList2String(data,2);
	        if (received_hash==my_hash){
		    	debug("(((((((((server(((((((((((((((( "+sloodleserverroot+" "+sloodlecontrollerid+" "+sloodlemoduleid+" my hash " +my_hash+ " received hash: "+received_hash);
		        //this is my grandchild because they have the same serverroot, controllerid, and moduleid as me!
		        key grandchild=llList2Key(data,1);
		        llListen(SLOODLE_CHANNEL_QUIZ_MASTER_REQUEST, "",grandchild, "");
		        if (llListFindList(GRAND_CHILDREN,[grandchild])==-1){
		        	GRAND_CHILDREN+=grandchild;
		         	
		         }
		         debug("\n\n\n\nYay! a grandchild! listening to "+llList2CSV(GRAND_CHILDREN));
		         
		        
    	   }
        }
       
        if (llListFindList(rezzed_hexes, [id])==-1&&llListFindList(GRAND_CHILDREN,[id])==-1){
        	debug("---------------not my relative!!");
        	llOwnerSay("---------------not my relative!!");
		    //return;
        }
         debug("continuing");
        if (channel==SLOODLE_CHANNEL_QUIZ_MASTER_REQUEST){
            if (command=="GET CONFIG"){
                   debug("sending config data");
                   llRegionSayTo(id,SLOODLE_CHANNEL_QUIZ_MASTER_RESPONSE, "receive config"+HEX_CONFIG_SEPARATOR+CONFIG);
                
            }else
            if (command=="LOAD QUIZ"){
                key user_key = llList2Key(data,1);
                debug("received load quiz - current question is: "+(string)current_question+ " num questions is : "+(string)num_questions);
                if (current_question>num_questions){
                    if (doRepeat==TRUE){
                        current_question=0;
                    }else{
                        //TODO finish quiz for all avatars
                         sloodle_translation_request(SLOODLE_TRANSLATE_SAY, [0], "no_more_questions", [], NULL_KEY, "hex_quizzer");
                        return;
                    }
                }
                integer question_id = llList2Integer(question_ids,current_question);
                current_question++;
                debug("sending quiz data");
                debug("sending: "+"receive quiz data"+HEX_CONFIG_SEPARATOR+QUIZ_DATA+"|"+(string)question_id+"|"+(string)current_question);
                llRegionSayTo(id,SLOODLE_CHANNEL_QUIZ_MASTER_RESPONSE, "receive quiz data"+HEX_CONFIG_SEPARATOR+QUIZ_DATA+"|"+(string)question_id+"|"+(string)current_question);
            }
         }
            
    }
}