//====================================================================================================
 /// <summary>
 /// create a feature list box
 /// </summary>
 /// <param name="CP"></param>
 /// <param name="feature"></param>
 /// <returns></returns>
 string getFeatureList(CPBaseClass CP, portalDataClass portal,  portalFeatureDataClass feature, string frameRqs )
 {
     string returnBody = "";
     string items = "";
     string qs;
     try
     {
         string activeNavHeading;
         activeNavHeading = feature.heading;
         formSimpleClass content = new formSimpleClass();
         foreach (KeyValuePair<string, portalFeatureDataClass> kvp in portal.featureList)
         {
             portalFeatureDataClass liFeature = kvp.Value;
             if ((liFeature.parentFeatureId == feature.id) && (liFeature.parentFeatureId != 0))
             {
                 string featureHeading = liFeature.heading;
                 if (string.IsNullOrEmpty(featureHeading))
                 {
                     featureHeading = liFeature.name;
                 }
                 if (liFeature.dataContentId != 0)
                 {
                     qs = frameRqs;
                     qs = CP.Utils.ModifyQueryString(qs, "addonid", "", false);
                     qs = CP.Utils.ModifyQueryString(qs, rnDstFeatureGuid, "", false);
                     qs = CP.Utils.ModifyQueryString(qs, "cid", liFeature.dataContentId.ToString());
                     items += "<li><a target=\"_blank\" href=\"?" + qs + "\">" + featureHeading + "</a></li>";
                 }
                 else
                 {
                     qs = frameRqs;
                     qs = CP.Utils.ModifyQueryString(qs, rnDstFeatureGuid, liFeature.guid);
                     items += "<li><a href=\"?" + qs + "\">" + featureHeading + "</a></li>";
                 }
             }
         }
         content.title = feature.heading;
         content.body = "<ul class=\"afwButtonList\">" + items + "</ul>";
         returnBody = content.getHtml(CP);
     }
     catch (Exception ex)
     {
         CP.Site.ErrorReport(ex, "adminFramework.portalClass.getFeatureList exception");
     }
     return returnBody;
 }
        //====================================================================================================
        /// <summary>
        /// If the portal does not exist in the Db, create it and all its features based on the portal argument
        /// </summary>
        /// <param name="CP"></param>
        /// <param name="newPortal"></param>
        public void savePortalToDb(CPBaseClass CP, portalDataClass newPortal)
        {
            try
            {
                CPCSBaseClass cs = CP.CSNew();
                CPCSBaseClass cs2 = CP.CSNew();
                //
                // insert or update the portal record
                //
                if (!cs.Open("portals", "ccguid=" + CP.Db.EncodeSQLText(newPortal.guid)))
                {
                    cs.Close();
                    cs.Insert("portals");
                    newPortal.id = cs.GetInteger("id");

                }
                newPortal.id = cs.GetInteger("id");
                cs.SetField("ccguid", newPortal.guid);
                cs.SetField("name", newPortal.name);
                cs.Close();
                //
                // insert or update portal feature records
                //
                foreach (KeyValuePair<string, portalFeatureDataClass> kvp in newPortal.featureList)
                {
                    portalFeatureDataClass feature = kvp.Value;
                    if (feature.guid != devToolGuid)
                    {
                        if (!cs.Open("portal features", "ccguid=" + CP.Db.EncodeSQLText(feature.guid)))
                        {
                            cs.Insert("portal features");
                            cs.SetField("ccGuid", feature.guid);
                        }
                        if (cs.OK())
                        {
                            feature.id = cs.GetInteger("id");
                            cs.SetField("portalId", newPortal.id.ToString());
                            cs.SetField("name", feature.name);
                            cs.SetField("heading", feature.heading);
                            cs.SetField("sortOrder", feature.sortOrder);
                            if (!string.IsNullOrEmpty(feature.addonGuid))
                            {
                                //
                                // lookup addon by guid, set addonid
                                //
                                if (cs2.Open("add-ons", "ccguid=" + CP.Db.EncodeSQLText(feature.addonGuid )))
                                {
                                    cs.SetField("addonId", cs2.GetInteger("id").ToString() );
                                }
                                cs2.Close();
                            }
                            if (!string.IsNullOrEmpty(feature.dataContentGuid))
                            {
                                //
                                // save dataContentId based on dataContentGuid
                                //
                                if (cs2.Open("content", "ccguid=" + CP.Db.EncodeSQLText(feature.dataContentGuid)))
                                {
                                    feature.dataContentId = cs2.GetInteger("id");
                                    cs.SetField("dataContentId", feature.dataContentId.ToString()  );
                                }
                                cs2.Close();
                            }
                            if (newPortal.defaultFeature.guid == feature.guid)
                            {
                                newPortal.defaultFeature = feature;
                            }
                        }
                        cs.Close();
                    }
                }
                //
                // lookup parent features by guid and set id
                //

                foreach (KeyValuePair<string, portalFeatureDataClass> kvp in newPortal.featureList)
                {
                    portalFeatureDataClass feature = kvp.Value;
                    if (feature.guid != devToolGuid)
                    {
                        if (!string.IsNullOrEmpty(feature.parentFeatureGuid))
                        {
                            //
                            // get the id of the parentFeature
                            //
                            if (cs.Open("portal features", "ccguid=" + CP.Db.EncodeSQLText(feature.parentFeatureGuid )))
                            {
                                feature.parentFeatureId = cs.GetInteger("id");
                            }
                            cs.Close();
                            if (feature.parentFeatureId > 0)
                            {
                                //
                                // set the parentFeatureId field of the current feature
                                //
                                if (cs.Open("portal features", "id=" + feature.id.ToString() ))
                                {
                                    cs.SetField("parentFeatureId", feature.parentFeatureId.ToString());
                                }
                                cs.Close();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                CP.Site.ErrorReport(ex, "exception in loadPortal");
            }
        }
        //====================================================================================================
        /// <summary>
        /// get a portal feature available to developers that provides tool for creating portals
        /// </summary>
        /// <param name="CP"></param>
        /// <returns></returns>
        string getDevTool(CPBaseClass CP, portalDataClass portal, string frameRqs )
        {
            string body = "Hello World";
            try
            {
                string section;
                //
                // this is a feature list, display the feature list
                //
                formSimpleClass content = new formSimpleClass();
                content.title = "Developer Tool";
                content.body = "";
                //
                // process snapshot tool
                //
                if(CP.Doc.GetText("button")=="Take Snapshot")
                {
                    CPCSBaseClass cs = CP.CSNew();
                    if (cs.Open("portals", "ccguid=" + CP.Db.EncodeSQLText(portal.guid)))
                    {
                        System.Web.Script.Serialization.JavaScriptSerializer msJson = new System.Web.Script.Serialization.JavaScriptSerializer() ;
                        string configJson = msJson.Serialize(portal);
                        cs.SetField("defaultConfigJson", configJson);
                    }
                    cs.Close();

                }
                //
                // output snapshot tool
                //
                section = "<h3>Portal Snapshot</h3>";
                section += "<p>Click the snapshot button to save the current features for this portal in the portal's default configuration field.</p>";
                section += CP.Html.Button("button", "Take Snapshot");
                section += "<p>Modify Portal and Portal Features data directly</p>";
                section += "<ul>";
                section += "<li><a href=\"?cid=" + CP.Content.GetID("Portals") + "\">Portals</a></li>";
                section += "<li><a href=\"?cid=" + CP.Content.GetID("Portal Features") + "\">Portal Features</a></li>";
                section += "</ul>";
                section = CP.Html.Form(section,"","","",frameRqs);
                content.body += section;
                //
                //
                //
                body = content.getHtml(CP);
            }
            catch (Exception ex)
            {
                CP.Site.ErrorReport(ex, "exception in loadPortal");
            }
            return body;
        }
 //====================================================================================================
 /// <summary>
 /// Return a portal object read from the Db based on the portal guid argument
 /// </summary>
 /// <param name="cp"></param>
 /// <param name="portalRecordGuid"></param>
 /// <returns></returns>
 public portalDataClass loadPortalFromDb(CPBaseClass CP, string selectSqlCriteria )
 {
     portalDataClass portal = new portalDataClass();
     portal.featureList = new Dictionary<string, portalFeatureDataClass>();
     try
     {
         //portalFeatureDataClass firstFeature = null;
         CPCSBaseClass csMan = CP.CSNew();
         CPCSBaseClass csFeature = CP.CSNew();
         string defaultConfigJson;
         if (!csMan.Open("portals", selectSqlCriteria,"id"))
         {
             //
             // create demo portal
             //
             csMan.Close();
             portal.name = "Empty";
             portal.guid = "";
             portal.id = 0;
             portal.featureList = new Dictionary<string, portalFeatureDataClass>();
             portalFeatureDataClass feature = new portalFeatureDataClass();
             feature.addonId = 0;
             feature.dataContentId = 0;
             feature.guid = "";
             feature.heading = "Sample";
             feature.id = 0;
             feature.name = "Demo";
             feature.parentFeatureId = 0;
             feature.sortOrder = "";
         }
         else
         {
             //
             // load portal
             //
             portal.name = csMan.GetText("name");
             portal.guid = csMan.GetText("ccguid");
             portal.id = csMan.GetInteger("id");
             int portalDefaultFeatureId = csMan.GetInteger("defaultFeatureId");
             defaultConfigJson = csMan.GetText("defaultConfigJson");
             csMan.Close();
             //
             // load portal links
             //
             portal.linkedPortals = new List<portalDataClass>();
             string sql = "select p.id,p.ccguid,p.name from ccPortals p left join ccPortalLinks l on l.toPortalId=p.id where l.fromPortalId=" + portal.id;
             if (csMan.OpenSQL(sql))
             {
                 do
                 {
                     portalDataClass linkedPortal = new portalDataClass();
                     linkedPortal.id = csMan.GetInteger("id");
                     //linkedPortal.guid = csMan.GetText( "ccguid");
                     //if (string.IsNullOrEmpty(linkedPortal.guid))
                     //{
                     //    linkedPortal.guid = CP.Utils.CreateGuid();
                     //    CP.Db.ExecuteSQL("update ccPortals set ccguid='"+linkedPortal.guid+"' where id=" + csMan.GetInteger("id"));
                     //}
                     linkedPortal.name = csMan.GetText("name");
                     portal.linkedPortals.Add( linkedPortal);
                     csMan.GoNext();
                 } while (csMan.OK());
             }
             csMan.Close();
             //
             // load features
             //
             if (!csFeature.Open("portal features", "portalid=" + portal.id, "sortOrder", true ))
             {
                 //
                 // no features found, load default portal features
                 //
                 csFeature.Close();
                 if (string.IsNullOrEmpty(defaultConfigJson))
                 {
                     //
                     // no default, fake a tab
                     //
                     portal.featureList = new Dictionary<string, portalFeatureDataClass>();
                     portalFeatureDataClass feature = new portalFeatureDataClass();
                     feature.addonId = 0;
                     feature.dataContentId = 0;
                     feature.guid = "";
                     feature.heading = "Sample";
                     feature.id = 0;
                     feature.name = "Demo";
                     feature.parentFeatureId = 0;
                     feature.sortOrder = "";
                     feature.addPadding = false;
                 }
                 else
                 {
                     //
                     // load default and save to Db
                     //
                     System.Web.Script.Serialization.JavaScriptSerializer msJson = new System.Web.Script.Serialization.JavaScriptSerializer();
                     //string configJson = msJson.Serialize(portal);
                     portal = msJson.Deserialize<portalDataClass>(defaultConfigJson);
                     savePortalToDb(CP, portal);
                     //
                     if (!string.IsNullOrEmpty(portal.defaultFeature.guid))
                     {
                         if (csFeature.Open("portal features", "ccguid=" + CP.Db.EncodeSQLText(portal.defaultFeature.guid)))
                         {
                             portal.defaultFeature = loadPortalFeatureFromCs(CP, csFeature);
                         }
                         csFeature.Close();
                     }
                 }
             }
             else
             {
                 //
                 // load features from Db
                 //
                 CPCSBaseClass cs2 = CP.CSNew();
                 do
                 {
                     portalFeatureDataClass feature = loadPortalFeatureFromCs(CP, csFeature);
                     portal.featureList.Add(csFeature.GetText("ccguid"), feature);
                     if (portal.defaultFeature == null)
                     {
                         portal.defaultFeature = feature;
                     }
                     if (portalDefaultFeatureId == feature.id)
                     {
                         portal.defaultFeature = feature;
                     }
                     csFeature.GoNext();
                 } while (csFeature.OK());
                 csFeature.Close();
             }
         }
     }
     catch (Exception ex)
     {
         CP.Site.ErrorReport(ex, "exception in loadPortal");
     }
     return portal;
 }