// Constructor adapted for use as a wrapper around that other Request Parameter
// thing (the one outside of the OgcFramework) since that bad boy is case
// sensitive, and we don't want it to be.
// We adapt this from the NameValueCollection class that came from the OgcFramework.
MgHttpRequestParameters::MgHttpRequestParameters(MgHttpRequestParam* pParams)
: m_pParams(pParams)
{
    MgStringPropertyCollection* p = m_pParams->GetParameters();
    SetCount(p->GetCount());

    for(int i=0; i< Count(); i++) {
      STRING sName = p->GetName(i);
      STRING sValue = p->GetValue(i);

      VPSZ pszName = szdup(sName.c_str());
      VPSZ pszValue = szdup(sValue.c_str());
      SetName(i,pszName);
      SetValue(i,pszValue);
    }
}
void c_FeatureReaderToHtml::ToTemplate(bool IsKml,c_RestDataReader* Reader, c_RestRequest* RestRequest
                            , const string& FullUri,const string& UriBase
                            ,string& HtmlStr,int StartIndex,int MaxCount)
{

  Ptr<MgClassDefinition> classdef;
  // classdef =  if( FeatureReader ) FeatureReader->GetClassDefinition() ;
  classdef = RestRequest->m_DataClassDef;
  if( !classdef ) return;
  
 
  
  //const c_CfgDataLayer* cfgdata = MgRest_MapNameToResourceId::GetCfgDataForClass(classfullname);
  const c_CfgDataResource* cfgresource = RestRequest->m_CfgDataResource;
  
  if( !cfgresource ) return; // error ; class has to be in configuration file
  
  const c_CfgRepTemplate* templatedata;
  if( RestRequest->m_CfgRepresentation->GetType() != c_CfgRepresentation::e_Template )
  {
    return;  
  }
  
  templatedata = (c_CfgRepTemplate*)RestRequest->m_CfgRepresentation;
    
  
  string rest_uri_part;
  if( cfgresource->m_RestUriPart.length() > 0 )
  {
    MgUtil::WideCharToMultiByte(cfgresource->m_RestUriPart,rest_uri_part);
    
  }
  else
  {
    rest_uri_part = "/rest/data/";
  }
  
  //ctemplate::Template::SetTemplateRootDirectory(g_HtmlTemplatePath);
  ctemplate::Template::SetTemplateRootDirectory(RestRequest->m_CfgDataResource->m_TemplateFolder);
  
  
  
   // get identity property name;
  STRING identname;      
  if( classdef )
  {
    Ptr<MgPropertyDefinitionCollection> idents = classdef->GetIdentityProperties();
    if( idents->GetCount() == 1) 
    {
      int ind=0;  
      Ptr<MgPropertyDefinition> identprop = idents->GetItem(ind);
      identname = identprop->GetName();
    }
    else
    {
      identname = L"";
    }
  }
  
  ctemplate::TemplateDictionary dict_main("KING.MGREST");
  
  // now fill in request parameters
  if( RestRequest )
  {
    Ptr<c_RestUriRequestParam> req_param = RestRequest->GetRequestParam();
    MgStringPropertyCollection* params = req_param->GetParameters();
    
    if( params && (params->GetCount()>0) )
    {
      string dictkey;
      string param_name,param_val;        
      string keyprefix = "REST_PARAM_";
      for(int ind=0;ind<params->GetCount();ind++)
      {
        Ptr<MgStringProperty> param = params->GetItem(ind);
        MgUtil::WideCharToMultiByte(param->GetName(),param_name);
        ReplaceSpaces(param_name); // google ctemplate doesn't allow spaces
        MgUtil::WideCharToMultiByte(param->GetValue(),param_val);
      
        
        dict_main.SetValue(keyprefix+param_name,param_val);
      }
    }
  }
  
  string resturiparam;
  bool ismorerecords=false;
  int featurecount=0;
  if( (classdef != NULL) && (Reader!=NULL) )
  {
    
    STRING wresturiparam = cfgresource->m_UriTag;
    
    MgUtil::WideCharToMultiByte(wresturiparam,resturiparam);
    
    
      bool isnext=true;
      int skipstart = StartIndex;
      if( skipstart > 0 )
      {
        
        while ( (skipstart>0) && (isnext=Reader->ReadNext())==true  )
        {
          skipstart--;
        }
        
      }
      if( isnext )
      {
        
        string dictname; // = mb_classname;
        MgUtil::WideCharToMultiByte(templatedata->m_HtmlTemp_Section,dictname);
        string nameprefix; // = mb_classname + "_";
        MgUtil::WideCharToMultiByte(templatedata->m_HtmlTemp_Prefix,nameprefix);
        
        while ( Reader->ReadNext() )
        {
          
          if( MaxCount >= 0 )
          {
            
            if( featurecount >= MaxCount ) 
            {
              ismorerecords=true;
              break; // go out
            }
          }
          ctemplate::TemplateDictionary* dict_section = dict_main.AddSectionDictionary(dictname);
          FillDictionary(dict_section,nameprefix,Reader);
          
          if( identname.length() > 0 )
          {
            STRING strval;
            string mb_strval;
            GetPropertyAsString(Reader,identname,strval);
            MgUtil::WideCharToMultiByte(strval,mb_strval);
            
            
            //
            string dictkey = nameprefix + "REST_PNG";  
            string val = UriBase + rest_uri_part + resturiparam + "/" + mb_strval + ".png";                
            dict_section->SetValue(dictkey,val);
              
            dictkey = nameprefix + "REST_HTML";  
            val = UriBase + rest_uri_part + resturiparam + "/" + mb_strval + ".html";  
            dict_section->SetValue(dictkey,val);
            
            dictkey = nameprefix + "REST_KML";  
            val = UriBase + rest_uri_part + resturiparam + "/" + mb_strval + ".kml";  
            dict_section->SetValue(dictkey,val);
            
            dictkey = nameprefix + "REST_KMZ";  
            val = UriBase + rest_uri_part + resturiparam + "/" + mb_strval + ".kmz";  
            dict_section->SetValue(dictkey,val);
            
            dictkey = nameprefix + "REST_XML";  
            val = UriBase + rest_uri_part + resturiparam + "/" + mb_strval + ".xml";  
            dict_section->SetValue(dictkey,val);
            
            dictkey = nameprefix + "REST_JSON";  
            val = UriBase + rest_uri_part + resturiparam + "/" + mb_strval + ".json";  
            dict_section->SetValue(dictkey,val);
            
            // create feature identifier value as base64 coded
            string ident_base64;
            GetPropertyAsBase64(Reader,identname,ident_base64);
            dictkey = nameprefix + "REST_IDENT_BASE64";  
            dict_section->SetValue(dictkey,ident_base64);
            
          }
          
          featurecount++;
        }
        
      }
    
  
    
    // Now check additional data to be fetched for html template
    // it applies only to single feature templates
    if( featurecount==1 && templatedata->GetCountHtmlExtraData() > 0 )
    {
      int count = templatedata->GetCountHtmlExtraData();
      for(int ind=0;ind<count;ind++)
      {
        const c_CfgRepTemplateExtraData* extradata = templatedata->GetHtmlExtraData(ind);
        
        if( extradata->m_FetchUri.length() > 0 )
        {
        
          // generate template unique name
          std::string filename,mb_str;
          MgUtil::WideCharToMultiByte(cfgresource->m_UriTag,filename);        
          MgUtil::WideCharToMultiByte(extradata->m_HtmlTemp_Prefix,mb_str);        
          filename += mb_str;
          
          
          MgUtil::WideCharToMultiByte(extradata->m_FetchUri,mb_str);
          filename="";
          ctemplate::Template * temp = ctemplate::Template::StringToTemplate(mb_str,ctemplate::STRIP_WHITESPACE);
          /*
          ctemplate::Template * temp = ctemplate::Template::RegisterStringAsTemplate(filename,        
                                               ctemplate::STRIP_WHITESPACE,ctemplate::TC_MANUAL,mb_str);
          */          
                    
          std::string uristr;                  
          temp->Expand(&uristr,&dict_main);     
          
          // Now use uristr to fetch data
          std::string mb_str2,mb_str3,mb_str4;
          
          MgUtil::WideCharToMultiByte(extradata->m_HtmlTemp_Section,mb_str2);
          MgUtil::WideCharToMultiByte(extradata->m_HtmlTemp_DataSection,mb_str3);
          MgUtil::WideCharToMultiByte(extradata->m_HtmlTemp_Prefix,mb_str4);
          c_RestFetchSource::FetchFeaturesToDictionary( uristr,&dict_main,mb_str2,mb_str3,mb_str4 );                                             
          
          delete temp;
        }
        
      }
    }
    
    // now add in dictionary values for next and previous
    if( ismorerecords || StartIndex>0 )
    {    
      Poco::URI uri_parser(FullUri);    
      
      std::string query = uri_parser.getQuery();
          
      c_RestUriRequestParam params;
      c_RestUri::ParseQuery(query.c_str(),&params);
      
      
      
      if( StartIndex>0 )
      {
        int newstart = StartIndex - MaxCount;
        if( newstart < 0 ) newstart=0;
        
        newstart++;        
        wchar_t strstart[20];
        ::swprintf(&strstart[0],L"%d",newstart);
        
        if( params.ContainsParameter(L"Start") )
        {
          params.SetParameterValue(L"Start",strstart);
        }
        else
        {
          params.AddParameter(L"Start",strstart);
        }
        
        wstring wuriquery;
        params.GetAsUriQuery(wuriquery);
        
        string uriquery;
        MgUtil::WideCharToMultiByte(wuriquery,uriquery);
        
        //string prev_uri = UriBase + rest_uri_part + resturiparam + "/" + ".html" + "?" + uriquery;
        string prev_uri = "?" + uriquery; // use only query part so link will be correct in case of url rewrites
        
        ctemplate::TemplateDictionary* dict_section = dict_main.AddSectionDictionary("PREVIOUS_PAGE_SECTION");
        string dictkey = "PREVIOUS_PAGE";  
        dict_section->SetValue(dictkey,prev_uri);
      }
      else
      {
        // no previous link
        //string dictkey = nameprefix + "PREVIOUS_PAGE";  
        //dict_main.SetEscapedValue(,);
      }
      
      
      if( ismorerecords>0 )
      {
        int newstart = StartIndex + MaxCount;
        if( newstart < 0 ) newstart=0;
        
        newstart++;        
        wchar_t strstart[20];
        ::swprintf(&strstart[0],L"%d",newstart);
        
        if( params.ContainsParameter(L"Start") )
        {
          params.SetParameterValue(L"Start",strstart);
        }
        else
        {
          params.AddParameter(L"Start",strstart);
        }
        
        wstring wuriquery;
        params.GetAsUriQuery(wuriquery);
        
        string uriquery;
        MgUtil::WideCharToMultiByte(wuriquery,uriquery);
        
        
        
        
        
        //string next_uri = UriBase + rest_uri_part + resturiparam + "/" + ".html" + "?" + uriquery;
        string next_uri = "?" + uriquery; // use only query part so link will be correct in case of url rewrites
        
        ctemplate::TemplateDictionary* dict_section = dict_main.AddSectionDictionary("NEXT_PAGE_SECTION");
        string dictkey = "NEXT_PAGE";          
        dict_section->SetValue(dictkey,next_uri);
                
      }
      else
      {
        // no previous link
        //string dictkey = nameprefix + "NEXT_PAGE";  
        //dict_main.SetEscapedValue(,);
      }

    }
  }
  
  
    string tmpl; // name of template to use    
  
  if(Reader)
  {
    
    if( featurecount == 1 )
      MgUtil::WideCharToMultiByte(templatedata->m_HtmlTemp_Single,tmpl);
    else
    {  
      if( featurecount == 0 )  
        MgUtil::WideCharToMultiByte(templatedata->m_HtmlTemp_Zero,tmpl);
      else
        MgUtil::WideCharToMultiByte(templatedata->m_HtmlTemp_Many,tmpl);
    }
  }
  else
  {
    // if there was no feature reader
    MgUtil::WideCharToMultiByte(templatedata->m_HtmlTemp_Error,tmpl);    
    if(RestRequest->m_RestResultObjectStatus  == c_RestRequest::e_BBox_OutOfRange )
      dict_main.ShowSection("EXCEPTION_BBOX_LIMIT");
    if(RestRequest->m_RestResultObjectStatus  == c_RestRequest::e_Count_OutOfRange )
      dict_main.ShowSection("EXCEPTION_COUNT_LIMIT");
  }    
    /*      
    string tmpl = mb_classname;
    // if there is only one feature then use different template
    // name of that template for class "parcel" is parcel.tpl , added "1" to end of class name
    if( count <= 1 )
    {
      tmpl.append("1");
    }
    
    tmpl.append(".tpl");
    */
    ctemplate::Template::ReloadAllIfChanged();
    
    ctemplate::TemplateContext tc;
    if( IsKml )
      tc = ctemplate::TC_XML;
    else
      tc = ctemplate::TC_HTML;
    
    //ctemplate::Template* tpl = ctemplate::Template::GetTemplateWithAutoEscaping(tmpl,ctemplate::DO_NOT_STRIP,tc);
    ctemplate::Template* tpl = ctemplate::Template::GetTemplate(tmpl,ctemplate::DO_NOT_STRIP);
    if( !tpl )
    {
      //Ptr<MgStringCollection> scol = new MgStringCollection();
      std::wstring wsarg;
      MgUtil::MultiByteToWideChar(tmpl,wsarg);
      //scol->Add(wsarg);
      
      std::wstring errmsg = L"Unable to load Template file '";
      errmsg = errmsg.append(wsarg);
      errmsg = errmsg.append(L"'. Check config file and template file location!");
      
      throw new MgRuntimeException(L"c_FeatureReaderToHtml::ToTemplate",__LINE__, __WFILE__, NULL, errmsg, NULL);
    }
    
    tpl->Expand(&HtmlStr,&dict_main);



}//end of c_FeatureReaderToHtml::ToTemplate