<?php
require_once("../../../../epconfig/TaquaLB/Elements/Elements.php"); 
require_once("../../../../epconfig/TaquaLB/Ajax/CGI/PHP/config.php");
AllowUser("RUpload");
require("../../../../epconfig/GenScript/PHP/getinfo.php");

//function to update repeat courses field
function UpdateRepeat($Rept,$grds,$processNumFailed = true,$CID="",$CDet =[]){
 // return "aaaa";
 // global $grds;
 //$processNumFailed => CourseNotExistInRst Insert
  global $courseID;
  global $courseDet;
  global $Lvl;
  global  $Sem;
  global  $studyID;
  $courseIDn = $CID == ""?$courseID:$CID;
  $courseDet = count($CDet) == 0?$courseDet:$CDet;
  $ReptArr = explode('+',$Rept);
 
  if((int)$grds['PASS'] > 0){ //if passed
           //remmove in new reapet if exist;
           $NewRepeat = "";
           if(isset($ReptArr[1])){
            $NewRepeat = str_replace(":$courseIDn:","",$ReptArr[1]);
           }
           $Rept = $ReptArr[0]."+".$NewRepeat;
           
           }else{ //if failed
             $allowfail = (int)$courseDet['AllowFail']; // number of times a student can fail the course
             if($allowfail != 0){ //if student not allow to resit atall i.e number of fail is 0 dont insert in repeat
              //add to new repeat
              if(isset($ReptArr[1])){
                
                // echo "@NewRept=".$ReptArr[1]."@";
                  if(strpos($ReptArr[1],":$courseIDn:") === false || ($allowfail < 0 && $processNumFailed)){ //if not exist in repeat or student can fail the course (allow to resit) at any number of times and the course result is just inputed the first time
                    $ReptArr[1] .= ":$courseIDn:";
                  }else{//if exist in repaet
                   if($processNumFailed){ //if insert operation i.e result inserted newly check allowable number of fail

                    //check the number of times it exixt 
                    $numocc = substr_count($ReptArr[0],":$courseIDn:");

                    if($numocc >= ($allowfail - 1)){ //if student has reach number of alowable fail, remove all occurence from repeat 
                     $ReptArr[1] = str_replace(":$courseIDn:","",$ReptArr[1]);

                    }else{ //if not ecceded number of fails add it
                     $ReptArr[1] .= ":$courseIDn:";
                    }
                   }
                    
                  }
              }else{ //if not exist add it
                $ReptArr[1] = ":$courseIDn:";
              }
             }
             $Rept = $ReptArr[0]."+".$ReptArr[1];
           }
           //print_r($grds);
    return $Rept;
}

//function to form rstinfo by the result string
function FormRstInfo($Rst){
  if(trim($Rst) == "")return '';
  global $dbo;
  $crstArr = is_array($Rst)?$Rst:$dbo->DataArray($Rst);
  if(count($crstArr) < 1)return '';
  $RstInfo = [];
             //loop through all result and form the result info
             foreach($crstArr as $CID => $ScoreDet){
               //get the course details
               $cdet = $dbo->SelectFirstRow("course_tb c, coursegroup_tb cg","c.*,cg.AllowFail","c.CourseID=$CID AND c.GroupID = cg.ID LIMIT 1");
               if(is_array($cdet)){ //if course details found
                $RstInfo[$CID] = ["CourseCode"=>$cdet['CourseCode'],"CourseStatus"=>$cdet['CourseStatus'],"Title"=>$cdet['Title'],"Lvl"=>$cdet['Lvl'],"DeptID"=>$cdet['DeptID'],"Sem"=>$cdet['Sem'],"CH"=>$cdet['CH'],"Elective"=>$cdet['Elective'],"StudyID"=>$cdet['StudyID'],"GroupID"=>$cdet['GroupID'],"StartSesID"=>$cdet['StartSesID'],"EndSesID"=>$cdet['EndSesID'],"AllowFail"=>$cdet['AllowFail']];
               }
             }
      return json_encode($RstInfo);
}

//function to update result info details
function UpdateRstInfo($RstInfo,$courseDet){
  $RstInfoArr = json_decode($RstInfo,true);
             $RstInfoArr = !is_array($RstInfoArr)?[]:$RstInfoArr;
             $RstInfoArr[$courseDet['CourseID']] = ["CourseCode"=>$courseDet['CourseCode'],"CourseStatus"=>$courseDet['CourseStatus'],"Title"=>$courseDet['Title'],"Lvl"=>$courseDet['Lvl'],"DeptID"=>$courseDet['DeptID'],"Sem"=>$courseDet['Sem'],"CH"=>$courseDet['CH'],"Elective"=>$courseDet['Elective'],"StudyID"=>$courseDet['StudyID'],"GroupID"=>$courseDet['GroupID'],"StartSesID"=>$courseDet['StartSesID'],"EndSesID"=>$courseDet['EndSesID'],"AllowFail"=>$courseDet['AllowFail']];
             return json_encode($RstInfoArr);
}

//function to recalculate Result
function Recalculate($RstDet,$update = true,$upward = true,$prevRept = NULL){
  global $dbo;
  global $schgrdstr;
  global $grdstr;
  global $classPassStr;
  global $classPassDetAll;
  global $updatetype;
  //global $courseID;
  
//check rst brouth forward is 0 and not the first result and not a upper result calculation, get it from imdiate previous result
if(($RstDet['BCH'] == 0 || $RstDet['BGP'] == 0) && ($RstDet['Lvl'] > 1 || ($RstDet['Lvl'] == 1 && $RstDet['Sem'] > 1) ) && $upward == true){ //if not first result and no brought forward
  //get the imediate previos result
$imprev = $dbo->Select("result_tb","","((Lvl = {$RstDet['Lvl']} && Sem < {$RstDet['Sem']}) OR Lvl < {$RstDet['Lvl']}) AND RegNo = '{$RstDet['RegNo']}' ORDER BY Lvl DESC, Sem DESC, GroupID DESC LIMIT 1");
//if imediate previous Found
if(is_array($imprev) && $imprev[1] > 0){
  //return ["SubQuery"=>"Prev seen"];
  $imprev = $imprev[0]->fetch_assoc();
  //Update the brouth forwards
  $RstDet['BCH'] = $imprev['CCH'];
  $RstDet['BGP'] = $imprev['CGP'];
}
}




//$GPA = $TCH > 0?number_format($TGP/$TCH,2):"0.00";
        $CGPA = (float)$RstDet['BCH'] > 0?(float)$RstDet['BGP']/(float)$RstDet['BCH']:0;
$rtn = ["TCH"=>0,"TGP"=>0,"CCH"=>$RstDet['BCH'],"CGP"=>$RstDet['BGP'],"BCH"=>$RstDet['BCH'],"BGP"=>$RstDet['BGP'],"SubQuery"=>"","GPA"=>0,"CGPA"=>$CGPA];
  $TCCH =0; $TGP =0;
  
  //return ["SubQuery"=>$dbo->DataString($RstDet['Rst'])];
  //check the Result type array or string
  $Rst = is_array($RstDet['Rst'])?$RstDet['Rst']:$dbo->DataArray($RstDet['Rst']);
  //if(count($Rst) < 1)return $rtn; //return empty result
  
$RstInfo = is_array($RstDet['RstInfo'])?$RstDet['RstInfo']:is_string($RstDet['RstInfo']) && trim($RstDet['RstInfo']) != ""?json_decode($RstDet['RstInfo'],true):[];
$RstInfo = is_null($RstInfo)?[]:$RstInfo;

$newRstInfo = [];
$Rept = "";

//Forming new reapet string
if(!is_null($prevRept)){ //if previous repet record sents (meaning repet need modification)
  $preptarr = explode("+",$prevRept);
if(count($preptarr) == 1){
  $Rept = $preptarr[0] ."+".$preptarr[0];
}else if(count($preptarr) > 1){
  $Rept = $preptarr[1] ."+".$preptarr[1];
}
}

$newrststr = []; //updated result
$TRC = 0; //total number of valid student result
  //loop through each result and calculate (main)
  foreach($Rst as $CID => $Score){
    
    $newrststr[$CID] = $Score;
    //get the individual score
      $indscore = explode("|",$Score);
      if(count($indscore) >= 2){ //if valid rst
        $TRC++;
        //#$#$
        $Tot = (int)$indscore[0] + (int)$indscore[1];
//if(count($indscore) > 2){ //if the grade details exist
      if(isset($RstInfo[$CID]) && (int)$updatetype < 1 && isset($RstInfo[$CID]["GradeStruc"])){ //if to update to result details and rst info exit
        $grds = GetGradeFromString($Tot,$RstInfo[$CID]["GradeStruc"]);
      }else{
        $grds = GetGrade($Tot,$grdstr,$schgrdstr);
      }
      
//}else{

//}
        
        if(isset($RstInfo[$CID]) && (int)$updatetype < 1){ //if course details exist and update type is to update to result details
          $cdet = $RstInfo[$CID];
        }else{
          $cdet = $dbo->Select("course_tb c, coursegroup_tb cg","c.*,cg.AllowFail","c.CourseID=$CID AND c.GroupID = cg.ID LIMIT 1");
          if(is_array($cdet) && $cdet[1] > 0){
            $cdet = $cdet[0]->fetch_assoc();
          //get the current grading structure
           $ngrdstruc = GetGrade(-1,$grdstr,$schgrdstr);
           $cdet["GradeStruc"] = $ngrdstruc;
          }
        }
      
        
//get course CH
$CH = 1;
if(is_array($cdet)){
  $CH = $cdet['CH'];
}
        $GP = $CH * $grds['Level'];
        $rtn['TCH'] += $CH;
        $rtn['TGP'] += $GP;

        //Add the result details to RstInfo
        $cdet['CA'] = $indscore[0];
        $cdet['Exam'] = $indscore[1];
        $cdet['Total'] = (float)$indscore[0] + (float)$indscore[1];
        $cdet['Point'] = $grds['Level'];
        $cdet['Grade'] = $grds['Grade'];
        $cdet['GradeName'] = $grds['Desc'];
        $cdet['Pass'] = $grds['PASS'];
        $cdet['GradePoint'] = $GP;


        $newRstInfo[$CID] = $cdet;
        //process Repeat
//if(trim($Rept) != ""){
  
  $Rept = UpdateRepeat($Rept,$grds,true,$CID,$cdet);
  
//}

$newrststr[$CID] = $indscore[0]."|".$indscore[1]."|".$grds['Level']."|".rawurlencode($grds['Grade'])."|".rawurlencode($grds['Desc'])."|".$grds['PASS']."|".$CH."|".$GP;

      }
  }

  if(trim($Rept) != ""){
    $RstDet['Rept'] = $Rept;
  }
  //update 
 // return ["SubQuery"=>json_encode($Rst)];
//calculate the cumulative
  $rtn['CCH'] = $rtn['TCH'] + $rtn['BCH'];
  $rtn['CGP'] = $rtn['TGP'] + $rtn['BGP'];
  $rtn['GPA'] = $rtn['TCH'] > 0?$rtn['TGP']/$rtn['TCH']:0;
  $rtn['CGPA'] = $rtn['CCH'] > 0?$rtn['CGP']/$rtn['CCH']:0;

  //for internal update, reset the class of pass parameters to interner record
if((int)$updatetype < 1 && isset($RstDet['COPRule']) && !is_null($RstDet['COPRule']) && trim($RstDet['COPRule']) != "" && isset($RstDet['COPDetails']) && !is_null($RstDet['COPDetails']) && trim($RstDet['COPDetails']) != ""){
  $classPassStr = $RstDet['COPRule'];
  $classPassDetAll = json_decode($RstDet['COPDetails'],true);
}
  $classPassdet = GetClassPass($rtn['CGPA'],$classPassStr,$classPassDetAll);
  $classOfPass = is_array($classPassdet)?$classPassdet['ClassName']:"";

  $query = "";
  //$RstDet['Rst'] = is_array($RstDet['Rst'])?$dbo->DataString($RstDet['Rst']):$RstDet['Rst'];
  $RstDet['Rst'] = $dbo->DataString($newrststr,false);
  
  //$newrststr
  if($update){ //if update
    $query .= "UPDATE result_tb SET Rst = '".$dbo->SqlSafe($RstDet['Rst'])."', Rept='{$RstDet['Rept']}', RstInfo='".$dbo->SqlSafe(json_encode($newRstInfo))."', TCH={$rtn['TCH']} , TGP={$rtn['TGP']}, BCH={$rtn['BCH']} , BGP={$rtn['BGP']} , CGP={$rtn['CGP']} , CCH={$rtn['CCH']}, GPA={$rtn['GPA']}, CGPA={$rtn['CGPA']},TRC=$TRC , COP='".$dbo->SqlSafe($classOfPass)."', COPRule='".$dbo->SqlSafe($classPassStr)."', COPDetails='".$dbo->SqlSafe(json_encode($classPassDetAll))."' WHERE ID = ".$RstDet["ID"].";";
  /*   if($RstDet['RegNo'] == 'AK15/NAS/BIO/081'){
      exit("UPDATE result_tb SET Rst = '".$dbo->SqlSafe($RstDet['Rst'])."', Rept='{$RstDet['Rept']}', RstInfo='".$dbo->SqlSafe(json_encode($newRstInfo))."', TCH={$rtn['TCH']} , TGP={$rtn['TGP']}, BCH={$rtn['BCH']} , BGP={$rtn['BGP']} , CGP={$rtn['CGP']} , CCH={$rtn['CCH']} WHERE ID = ".$RstDet["ID"].";");
    } */
  }else{ //if insert
    $query .= "INSERT INTO result_tb (`RegNo`, `Lvl`, `Sem`, `SesID`, `Rst`, `Outst`,`Rept`,`GroupID`,`CGP`,`CCH`,`TGP`,`TCH`,`BGP`,`BCH`,RstInfo,GPA,CGPA,TRC,COP,COPRule,COPDetails) VALUES ('{$RstDet['RegNo']}',{$RstDet['Lvl']},{$RstDet['Sem']},{$RstDet['SesID']},'".$dbo->SqlSafe($RstDet['Rst'])."', '{$RstDet['Outst']}', '{$RstDet['Rept']}', {$RstDet['GroupID']},{$rtn['CGP']} , {$rtn['CCH']},{$rtn['TGP']},{$rtn['TCH']},{$rtn['BGP']},{$rtn['BCH']},'".$dbo->SqlSafe(json_encode($newRstInfo))."', {$rtn['GPA']},{$rtn['CGPA']},$TRC,'".$dbo->SqlSafe($classOfPass)."','".$dbo->SqlSafe($classPassStr)."','".$dbo->SqlSafe(json_encode($classPassDetAll))."');";
  }

 
  //check down result calculation
if($upward){
 
  //get all upward resultfrom the current result
$upwardRst = $dbo->Select("result_tb","","((Lvl = {$RstDet['Lvl']} AND Sem > {$RstDet['Sem']}) OR Lvl > {$RstDet['Lvl']}) AND RegNo = '{$RstDet['RegNo']}' ORDER BY Lvl,Sem");

if(is_array($upwardRst) && $upwardRst[1] > 0){
  
  $CarryBCH = $rtn['CCH'];$CarryBGP = $rtn['CGP'];$PreRepeat = $RstDet['Rept'];
  //return ["SubQuery"=>$RstDet['RegNo'] . " ; ".$upwardRst[1]];
   while($upwrst = $upwardRst[0]->fetch_assoc()){ //loop trough all the upward results
    
    $upwrst['BCH'] = $CarryBCH; $upwrst['BGP'] = $CarryBGP; //update the Brought forwards
    
//recalculate the result
      $newrst =  Recalculate($upwrst,true,false,$PreRepeat); //recalculate the result only
      
      //exit(json_encode($newrst));
      $query .= $newrst["SubQuery"]; //get the update query
      //return ["SubQuery"=>json_encode($upwrst)];
      $CarryBCH = $newrst['CCH'];$CarryBGP = $newrst['CGP']; //set the next Brought forward to the current cummulatives
      $PreRepeat = $newrst['Rept'];
   }
}

//$query

}


//add the query
$rtn["SubQuery"] = $query;
$rtn["Rept"] = $RstDet['Rept'];

//exit(json_encode($rtn));
return $rtn;

}

//function to get grades based on updatetype
function GetGradeLocal($scorestr = "",$CA,$EX,$grdstr,$schgrdstr){
global $updatetype;
$tot = (int)$CA + (int)$EX;
/* $brdw = explode("|",$scorestr);
if($updatetype == 0 && count($brdw) > 2){ //if to use result existing settings and if it exist
   $grds = ["Level"=>$brdw[2],"Grade"=>$brdw[3],"Desc"=>$brdw[4],"PASS"=>$brdw[5]];
  // $grds["ScoreStr"] = $brdw[0]."|".$brdw[1]."|".$grds['Level']."|".$grds['Grade']."|".$grds['Desc']."|".$grds['PASS'];
}else{ */
  $grds = GetGrade($tot,$grdstr,$schgrdstr);
  
//}
$grds["ScoreStr"] = $CA."|".$EX."|".$grds['Level']."|".$grds['Grade']."|".$grds['Desc']."|".$grds['PASS'];
return $grds;
}

//function to form result update/insert query string
function FormResultQuery($GroupID = 1,$insert = true){
  //import globals into functions
 global  $discolDS;
 global $sdatastrDS;
 global $rstparamDS;
 global $dbo;
  //var fields = ["sestb","rstudstudy","rstudfac","rstuddept","rstudprog","rstudlvl","semest"];
 global $Lvl;
  global  $Sem;
  global  $Ses;
  global  $progid;
  global  $courseID;
  global  $studyID;
  global $courseDet;
  global $schgrdstr;
  global $grdstr;
  global $updatetype;
   $totrw = (int)$sdatastrDS["MaxDataRow"]; //total datarow sent
  //$update string;
  $query = "";
  $fcoursID = $courseID;
  
          $CH = (int)$courseDet['CH'];
  //loop through each row
  for($rw=1; $rw <= $totrw; $rw++){
      $RegNo = rawurldecode($sdatastrDS[$rw."_".$discolDS['RegNo']]);
      $Readonly = rawurldecode($sdatastrDS[$rw."_readonly"]);
      $Disable = rawurldecode($sdatastrDS[$rw."_disable"]);
      //Get the student Current CA and Exam
     $CA = rawurldecode($sdatastrDS[$rw."_".$discolDS['CA']]);
     $Exm = rawurldecode($sdatastrDS[$rw."_".$discolDS['Exm']]);
     $RstCourseID = (int)rawurldecode($sdatastrDS[$rw."_".$discolDS['RstRegCID']]);
     $courseID = $RstCourseID > 0?$RstCourseID:$fcoursID;
     //exit($RstCourseID);
     //if(trim($RegNo) == "" || $Readonly == "true" || $Disable == "true" || (trim($CA) == "" && trim($Exm) == "") ){ //if no regno proceed to next row or result is outdated
      if(trim($RegNo) == "" || $Readonly == "true" || $Disable == "true" ){ //if no regno proceed to next row or result is outdated
        continue;
      }
      $proccnumfailed = true; //proccess result based on allowable number of failed
      $couseExistInRept = false;
//AK17/NAS/BIO/032
      


$CA = (float)$CA; $Exm = (float)$Exm;
      
    
     
     //

     //Form The result string
     
    $tot = (float)$CA + (float)$Exm;

   //$grds = GetGrade($tot,$grdstr,$schgrdstr);

    //a safer approach to get student level in a particular sesion is to get it from course registration, if not exit fall back to old calculating method
    $Lvl = StudLevelSesSafe($RegNo,$Ses);
    
   // exit($StudCourseRegSes);
    //calculate student level 
    //$Lvl = StudLevelSes($RegNo,$Ses);
     //get the student result 
     $studrst = $dbo->Select("result_tb","","RegNo='$RegNo' AND Lvl=$Lvl AND Sem=$Sem AND SesID=$Ses AND GroupID >= $GroupID");
     if(is_array($studrst)){
       //check if record exist 
       if($studrst[1] > 0){//result found
         while($indstudrst = $studrst[0]->fetch_assoc()){
         
           $crst = $indstudrst['Rst'];
           
          // $rstinfo = trim($indstudrst['RstInfo']) == "" || trim($indstudrst['RstInfo']) == "[]"?[]:json_decode($indstudrst['RstInfo'],true);
           //$CGP = (int)$indstudrst['CGP'];
           //$CCH = (int)$indstudrst['CCH'];
           //New
           //$TGP = (int)$indstudrst['TGP'];
           //$TCH = (int)$indstudrst['TCH'];
           //New
           $crstArr = $dbo->DataArray($crst);
           
           //get the old score and calculate GP/CH, then subtract from total GP & CH. Calculate the new and add respectively
           //*************************************************
          /*  if(isset($crstArr[$courseID])){ //if result exit
           $proccnumfailed = false;
           $couseExistInRept = true;
             $oldscore = $crstArr[$courseID];
             //get ca and exam
             $oldscoreArr = explode("|",$oldscore);
             if(count($oldscoreArr) == 2){
               $oldTot = (int)$oldscoreArr[0] + (int)$oldscoreArr[1];
               $oldgrds = GetGrade($oldTot,$grdstr,$schgrdstr);
               $oldGP = $CH * $oldgrds['Level'];
               
               //deduct oldGP and oldCH from CGP and CCH respectively
               $CGP -= $oldGP;
               $CCH -= $CH;

             }
             
           }
 */
           //**************************************************
           $crstArr[$courseID] = isset($crstArr[$courseID])?$crstArr[$courseID]:"";
            //check if Back Save
           /*  if($updatetype  < 1 && isset($rstinfo[$courseID]['GradeStruc'])){
               //get 
               $grds = GetGradeFromString($Tot,$rstinfo[$courseID]["GradeStruc"]);
            }else{
              $grds = GetGrade($tot,$grdstr,$schgrdstr);
            }
            */
           //exit(json_encode($grds));
$scoreb4 = $crstArr[$courseID];
$scoreb4 = explode("|",$scoreb4);
 //check if no changes found - if normal save, and CA and Exam are the same (cos the system will use the result info so there will be no change)
// exit($updatetype);
 if($updatetype < 1 && count($scoreb4) >= 2 && (float)$scoreb4[0] == $CA && (float)$scoreb4[1] == $Exm){
   
  continue;
} 
//if(count())
           //update the score
           $crstArr[$courseID] = $CA."|".$Exm;
           //will be properly format (includes the grading details) in Recalculate
          //$grdPoint = (int)$grds['Level']; //get the grade point
          //$newGP = $CH * $grdPoint;
          
           $urst = $dbo->DataString($crstArr,false);
          
           
           //calculate cummulatives 
           //$CGP += $newGP;
           //$CCH += $CH;

           //$Rept = $indstudrst['Rept'];
           //$Rept = UpdateRepeat($Rept,$grds,$proccnumfailed);


           /* $RstInfo = $crst['RstInfo'];
           //check if result info exist
           if(is_null($RstInfo) || trim($RstInfo) == ""){
            $RstInfo = FormRstInfo($crstArr);
           }else{ //if RstInfo already exist
             $RstInfo = UpdateRstInfo($RstInfo,$courseDet);
           } */
          // $query .= $tot."|".$grds['PASS'].";";
          $indstudrst['Rst'] = $urst;


          //$indstudrst['Rept'] = $Rept;

          
          //$indstudrst['CGP'] = $CGP;
          //$indstudrst['CCH'] = $CCH;
          
            //recalculate result
            $newcalc = Recalculate($indstudrst);
            
            if($newcalc['SubQuery'] != ""){
              $query .= $newcalc['SubQuery'] ;
              //echo $query;
            }
            
         }
        
       }else{//no result found
         //$query .= $tot."|".$grds['PASS'].";";
          if($GroupID > 1){ //meaning lower result group exist
            //Get the imideate result 
            $imdrst = $dbo->SelectFirstRow("result_tb","","RegNo='$RegNo' AND Lvl=$Lvl AND Sem=$Sem AND SesID=$Ses AND GroupID < $GroupID ORDER BY GroupID DESC Limit 1");
            if(is_array($imdrst)){
              //if immediate result found
              $crst = $imdrst['Rst'];
              //$imCGP = (int)$imdrst['CGP'];
              //$imCCH = (int)$imdrst['CCH'];
              $crstArr = $dbo->DataArray($crst);
              //Get the old immediate score, calculate GP
              /* if(isset($crstArr[$courseID])){
                $imdoldscore = $crstArr[$courseID];
                $imdoldscoreArr = explode("|",$imdoldscore);
                if(count($imdoldscoreArr) == 2){
                  $imdoldtot = $imdoldscoreArr[0] + $imdoldscoreArr[1];
                  $imoldgrds = GetGrade($imdoldtot,$grdstr,$schgrdstr);
                 $imoldGP = $CH * $imoldgrds['Level'];
               
               //deduct oldGP and oldCH from CGP and CCH respectively
                  $imCGP -= $imoldGP;
                  $imCCH -= $CH;
                }
              } */
              //$crstArr[$courseID] = $ScoreStr;
              $crstArr[$courseID] = isset($crstArr[$courseID])?$crstArr[$courseID]:"";
           //$grds = GetGradeLocal($crstArr[$courseID],$CA,$Exm,$grdstr,$schgrdstr);
           if($crstArr[$courseID] != ""){
             $prevrst = explode("|",$crstArr[$courseID]);
             if($CA == (float)$prevrst[0] && $Exm == (float)$prevrst[1])continue;  
             }
           //update the score
           $crstArr[$courseID] = $CA."|".$Exm;
          //$grdPoint = (int)$grds['Level']; //get the grade point
          //$newGP = $CH * $grdPoint;
              $urst = $dbo->DataString($crstArr,false);
              //check if update done
              /* if($crst == $urst){
                continue;
              } */
              $Rept = $imdrst['Rept'];
              $OutSt = $imdrst['Outst'];

              //$imdrst['Rept'] = UpdateRepeat($Rept,$grds,true);

              //set the new GroupID
              $imdrst['GroupID'] = $GroupID;

              //set the new rst
              $imdrst['Rst'] = $urst;

              //add the new result GP and CH to the CGP and CCH
              //$imCGP += $newGP;
                  //$imCCH += $CH;
                  $newcalc = Recalculate($imdrst,false); //perform insert
            if($newcalc['SubQuery'] != ""){
              $query .= $newcalc['SubQuery'] ;
            }
              //form insert
               // $query .= "INSERT INTO result_tb (`RegNo`, `Lvl`, `Sem`, `SesID`, `Rst`, `Outst`,`Rept`,`GroupID`,`CGP`,`CCH`) VALUES ('$RegNo',$Lvl,$Sem,$Ses,'$urst', '$OutSt', '$Rept', $GroupID,$imCGP , $imCCH);";
            }
          }else{// meaning no result exist atall
          $Rept = '';$OutSt='';
          //form imedite level sem
         // $implvlsem = GetPrevLvlSem($Lvl,$Sem);
          $imdCGP = 0;$imdCCH=0;
         // if($implvlsem['err'] == ""){
           /* $imLvl = $implvlsem['level'];$imSem = $implvlsem['semester'];
            $imdrst = $dbo->SelectFirstRow("result_tb","","RegNo='$RegNo' AND Lvl=$imLvl AND Sem=$imSem ORDER BY ID DESC Limit 1");*/
            $imdrst = GetPrevResult($RegNo,$Lvl,$Sem);
            $Rept = ""; $iTCH = $iTGP = $iBCH = $iBGP = $iCCH = $iCGP = 0;
            if(is_array($imdrst)){//if exist
               $Rept = $imdrst['Rept'];
               $ReptArr = explode("+",$Rept);
               if(count($ReptArr) > 1){
                 $Rept = $ReptArr[1]."+".$ReptArr[1];
               }
               $OutSt = $imdrst['Outst'];
               $OutStArr = explode("+",$OutSt);
               if(count($OutStArr) > 1){
                 $OutSt = $OutStArr[1]."+".$OutStArr[1];
               }
               
               $iCGP = $iBGP = $imdCGP = (int)$imdrst['CGP'];
               $iBCH = $iCCH = $imdCCH = (int)$imdrst['CCH'];
            }
            //update the repeat str
            //$Rept = UpdateRepeat($Rept,$grds,true);
         // }
         //$crstArr[$courseID] = isset($crstArr[$courseID])?$crstArr[$courseID]:"";
           //$grds = GetGradeLocal("",$CA,$Exm,$grdstr,$schgrdstr);
           //update the score
           $ScoreStr = $grds['ScoreStr'];
         // $grdPoint = (int)$grds['Level']; //get the grade point
         // $newGP = $CH * $grdPoint;
          $urst = $courseID."=".$CA."|".$Exm;
          //$imdCCH += $CH;
          //$imdCGP += $newGP;

          /* $query .= "INSERT INTO result_tb (`RegNo`, `Lvl`, `Sem`, `SesID`, `Rst`, `Outst`,`Rept`,`GroupID`,`CGP`,`CCH`,`TGP`,`TCH`,`BGP`,`BCH`,RstInfo) VALUES ('{$RstDet['RegNo']}',{$RstDet['Lvl']},{$RstDet['Sem']},{$RstDet['SesID']},'{$RstDet['Rst']}', '{$RstDet['Outst']}', '{$RstDet['Rept']}', {$RstDet['GroupID']},{$rtn['CGP']} , {$rtn['CCH']},{$rtn['TGP']},{$rtn['TCH']},{$rtn['BGP']},{$rtn['BCH']},'".$dbo->SqlSafe(json_encode($newRstInfo['RstInfo']))."');"; */
        $RstArr = ['RegNo'=>$RegNo,'Lvl'=>$Lvl,'Sem'=>$Sem,'SesID'=>$Ses,'Rst'=>$urst,'Outst'=>$OutSt,'Rept'=>$Rept,'GroupID'=>$GroupID,'GroupID'=>$GroupID,"TCH"=>$iTCH,"TGP"=>$iTGP,"BCH"=>$iBCH,"BGP"=>$iBGP,"CCH"=>$iCCH,"CGP"=>$iCGP,"RstInfo"=>"","COP"=>""];
        $newcalc = Recalculate($RstArr,false); //perform insert
        if($newcalc['SubQuery'] != ""){
          $query .= $newcalc['SubQuery'] ;
        }
         //  $query .= "INSERT INTO result_tb (`RegNo`, `Lvl`, `Sem`, `SesID`, `Rst`, `Outst`,`Rept`,`GroupID`,`CGP`,`CCH`) VALUES ('$RegNo',$Lvl,$Sem,$Ses,'$urst','$OutSt','$Rept',$GroupID,$imdCGP,$imdCCH);";

          }
       }
     }
  }
  return $query;
}



//discol&sdatastr&rstparam
if(isset($_POST['discol'])){
  
  //get grading structure
  $grdstr = $dbo -> SelectFirstRow("resultinfo_tb","","ID = (select GrdStrucID from school_tb limit 1)");
  //$grdstr = $dbo -> SelectFirstRow("resultinfo_tb","","ID = (select GrdStrucID from school_tb limit 1)");
$classPassStr = $grdstr['ClassOfPass'];
          $grdstr = is_array($grdstr)?$grdstr[1]:"";
          $schgrdstr = GetGradeDetAll();
          $classPassDetAll = GetClassPassDetAll();
  extract($_POST);
  //exit($sdatastr);
  //form data strings
  $discolDS = $dbo->DataArray($discol);
  $sdatastrDS = $dbo->DataArray($sdatastr);
  $rstparamDS = $dbo->DataArray($rstparam);

  //var fields = ["sestb","rstudstudy","rstudfac","rstuddept","rstudprog","rstudlvl","semest"];
  $Lvl = rawurldecode($rstparamDS["rstudlvl"]);
  $Sem = rawurldecode($rstparamDS["semest"]);
  $Ses = rawurldecode($rstparamDS["sestb"]);
  $progid = rawurldecode($rstparamDS["rstudprog"]);
  $courseID = rawurldecode($rstparamDS["rcourse"]);

  $studyID = rawurldecode($rstparamDS["rstudstudy"]);

  //Get the Result Course Details
  $courseDet = $dbo->SelectFirstRow("course_tb c, coursegroup_tb cg","c.*,cg.AllowFail","c.CourseID=$courseID AND c.GroupID = cg.ID LIMIT 1");

  $isupdate = false;
  //print_r($courseDet);
  //exit();
  if(!is_array($courseDet)){
    exit("#Invalid Course");
  }
  //$studcourses = GetCourses($progid,$Lvl,$Sem);
  //Check if Approval row Exist
  $apprst = $dbo->SelectFirstRow("resultapprove_tb","","ProgID = $progid AND Ses = $Ses AND Lvl = $Lvl AND Sem = $Sem AND CourseID = $courseID AND StudyID = $studyID ORDER BY GroupID DESC LIMIT 1");
  //$apprv = null;//hold the result approval status 
  $query = ""; //holds the entire query to run at the end
  if(!is_array($apprst)){ //if not exist
       $query .= "INSERT INTO `resultapprove_tb`(`ProgID`, `Ses`, `Lvl`, `Sem`, `CourseID`, `StudyID`, `Status`, `GroupID`) VALUES ($progid,$Ses,$Lvl,$Sem,$courseID,$studyID,'FALSE',1);";
       $query .= FormResultQuery(1); //form the result query for the new group
  }else{ //if approval exist
       $AppGroupID = $apprst["GroupID"];
       $Status = $apprst["Status"];
       //check Stautus 
       if($Status == "TRUE"){ //if result is approved
         exit("Operation Aborted, Result Already Approved");
       }else{ //if not approved
         $query .= FormResultQuery($AppGroupID); //form the result query for the current group id
       }
  }
//exit($query);
 if(trim($query) != ""){
  $dump = $dbo->Connection->multi_query($query);
  if(!$dump){
    echo "#Server Error: ".$dbo->Connection->error;
  }else{
     echo "*Result Saved";
  }
 }else{
   echo "No Change Found";
 }
  
}



?>