/*******************************************************************************
 * Copyright (c) 2023, Jan Koester jan.koester@gmx.net
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 * Neither the name of the <organization> nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

#include <iostream>
#include <cstring>
#include <string>

#include <dbpp/database.h>

#include "plugin.h"
#include "theme.h"
#include "conf.h"
#include <i18n.h>

#include <htmlpp/exception.h>

namespace blogi {
    class Navbar : public PluginApi {
    public:
        Navbar(){
        }

        ~Navbar(){
        }

        const std::string getName(){
            return "navbar";
        }

        const std::string getVersion(){
            return "0.1";
        }

        const std::string getAuthor(){
            return "Jan Koester";
        }

        void initPlugin(){
            registerGPO("5bdb2bca-fdfe-40f6-9898-f2464189d1f6",
                        "Blogi: Navbar Settings",
                        "Controls access to navigation bar settings",
                        true);

            dbpp::SQL sql;
            dbpp::DBResult res;

            sql << "CREATE TABLE IF NOT EXISTS navbar("
                <<   "id integer PRIMARY KEY " << Args->database[0]->autoincrement(sql) << ","
                <<   "name character varying(255) NOT NULL,"
                <<   "container_id character varying(255) NOT NULL"
                << "); "
                << "CREATE TABLE IF NOT EXISTS navbar_items("
                <<   "id integer PRIMARY KEY " << Args->database[0]->autoincrement(sql) << ","
                <<   "name character varying(255) NOT NULL,"
                <<   "url character varying(255) NOT NULL,"
                <<   "type integer default 0,"
                <<   "navbar_id integer,"
                <<   "FOREIGN KEY (navbar_id) REFERENCES navbar (id)"
                << ");";
            Args->database[0]->exec(sql,res);
            return;
        }

        void Rendering(const int tid,libhttppp::HttpRequest &req,libhtmlpp::HtmlElement* curpage,int type,const std::string &sessionid){
            dbpp::SQL sql,sql2;
            dbpp::DBResult res,res2;
            sql << "select id,name,container_id from navbar";

            std::string turl=req.getRequest();
            if(turl.rfind('?')>0){
                turl=turl.substr(0,turl.rfind('?'));
            }

            int n = Args->database[tid]->exec(sql,res);
            if(n<1){
                return;
            }

            for (int i = 0; i < n; i++) {
                libhtmlpp::HtmlString buf;
                buf << "<ul>";

                sql2 << "select url,name,type from navbar_items WHERE navbar_id='" << res[i][0] << "' ORDER BY id";

                int n2 = Args->database[tid]->exec(sql2,res2);
                for (int ii = 0; ii < n2; ii++) {
                    buf << "<li ";
                    if(turl.compare(0,strlen(res2[ii][0]),res2[ii][0]) == 0 )
                        buf << "class=\"active\"";
                    else
                        buf << "class=\"inactive\"";
                    if(strcmp(res2[ii][2],"0")==0)
                        buf << "><a href=\"" << res2[ii][0] << "\">" << res2[ii][1] << "</a></li>";
                    else
                        buf << "><span id=\"" << res2[ii][1] << "\" >" << res2[ii][0] << "</span></li>";
                }
                buf << "</ul>";

                sql2.clear();
                if(curpage->getElementbyID(res[i][2])){
                    try{
                        libhtmlpp::Element &el=buf.parse();
                        curpage->getElementbyID(res[i][2])->appendChild(el);
                    }catch(libhtmlpp::HTMLException &e){
                        libhttppp::HTTPException excep;
                        excep[libhttppp::HTTPException::Critical] << e.what();
                        throw excep;
                    }
                }
            }

        }

        bool haveSettings(){
            return true;
        }

        json_object* delNavigation(const int tid,libhttppp::HttpRequest &req){
            int navid=-1;
            bool confirmed=false;
            libhttppp::HttpForm form;
            form.parse(req);
            std::string _lang = getLang(*Args->database[tid]);

            for(const auto &cdat : form.urlData()){
                if(cdat.key=="navid")
                    navid=atoi(cdat.value.c_str());

                if(cdat.key=="confirmed")
                    if(cdat.value=="true")
                        confirmed=true;
            }

            if(navid<0){
                libhttppp::HTTPException excep;
                excep[libhttppp::HTTPException::Critical] << "No navbar selectet for remove";
                throw excep;
            }

            json_object *jroot = json_object_new_object();
            json_object_object_add(jroot, "title", json_object_new_string(tr(_lang,"Remove Navigation").c_str()));

            if(!confirmed){
                json_object *jconfirm = json_object_new_object();
                json_object_object_add(jconfirm, "message", json_object_new_string(tr(_lang,"Do you want to remove this navigation?").c_str()));
                std::string yesUrl = Args->config->buildurl("settings/navbar/delnav?navid=") + std::to_string(navid) + "&confirmed=true";
                json_object_object_add(jconfirm, "yes_url", json_object_new_string(yesUrl.c_str()));
                json_object_object_add(jconfirm, "no_url", json_object_new_string(Args->config->buildurl("settings/navbar").c_str()));
                json_object_object_add(jroot, "confirm", jconfirm);
                return jroot;
            }

            dbpp::SQL sql;
            dbpp::DBResult res;

            sql << "delete from navbar_items WHERE navbar_id='" << navid <<"'; ";
            sql << "delete from navbar WHERE id='" << navid <<"';";

            Args->database[tid]->exec(sql,res);

            json_object_object_add(jroot, "message", json_object_new_string(tr(_lang,"Successfully removed navigation.").c_str()));
            json_object_object_add(jroot, "message_type", json_object_new_string("success"));

            json_object *jnav = json_object_new_array();
            json_object *jback = json_object_new_object();
            json_object_object_add(jback, "label", json_object_new_string(tr(_lang,"Back to list").c_str()));
            json_object_object_add(jback, "url", json_object_new_string(Args->config->buildurl("settings/navbar").c_str()));
            json_object_array_add(jnav, jback);
            json_object_object_add(jroot, "nav", jnav);

            return jroot;
        }

        json_object* editNavigation(const int tid,libhttppp::HttpRequest &req){
            int navid=-1,rem_itemid=-1;
            dbpp::SQL sql;
            dbpp::DBResult res;
            std::vector<char> sbuf;

            std::string navname,container_id,newitem_name,newitem_url,newitem_type;

            libhttppp::HttpForm form;
            form.parse(req);
            std::string _lang = getLang(*Args->database[tid]);

            for(const auto &cdat : form.urlData()){
                if(cdat.key=="navid")
                    navid=atoi(cdat.value.c_str());
                else if(cdat.key=="navname")
                    libhtmlpp::HtmlDecode(cdat.value,navname);
                else if(cdat.key=="navcontainer")
                    container_id=cdat.value;
                else if(cdat.key=="navitem_name_new")
                     libhtmlpp::HtmlDecode(cdat.value,newitem_name);
                else if(cdat.key=="navitem_url_new")
                    newitem_url=cdat.value;
                else if(cdat.key=="navitem_type_new")
                    newitem_type=cdat.value;
                else if(cdat.key=="navitem_remove")
                    rem_itemid=atoi(cdat.value.c_str());
            }

            if(navid<0){
                libhttppp::HTTPException excep;
                excep[libhttppp::HTTPException::Critical] << "No navbar selectet for edit";
                throw excep;
            }

            auto changeItemName = [this,tid,navid](const std::string &key,const std::string &value){
                int iid;
                sscanf(key.c_str(),"navitem_name_%d",&iid);
                dbpp::SQL sql2;
                dbpp::DBResult res2;
                std::vector<char> sbuf;
                sql2 << "UPDATE navbar_items SET name='"<< sql2.escaped(sbuf,value.c_str()) << "' WHERE navbar_id='" << navid << "' AND id='" << iid << "'";
                Args->database[tid]->exec(sql2,res2);
                sql2.clear();
            };

            auto changeItemUrl = [this,tid,navid](const std::string &key,const std::string &value){
                int iid;
                sscanf(key.c_str(),"navitem_url_%d",&iid);
                dbpp::SQL sql2;
                dbpp::DBResult res2;
                std::vector<char> sbuf;
                sql2 << "UPDATE navbar_items SET url='"<< sql2.escaped(sbuf,value.c_str()) << "' WHERE navbar_id='" << navid << "' AND id='" << iid << "'";
                Args->database[tid]->exec(sql2,res2);
                sql2.clear();

            };

            auto changeItemType = [this,tid,navid](const std::string &key,const std::string &value){
                int iid;
                sscanf(key.c_str(),"navitem_type_%d",&iid);
                dbpp::SQL sql2;
                dbpp::DBResult res2;
                std::vector<char> sbuf;
                sql2 << "UPDATE navbar_items SET type='" << sql2.escaped(sbuf,value.c_str()) << "' WHERE navbar_id='" << navid << "' AND id='" << iid << "'";
                Args->database[tid]->exec(sql2,res2);
                sql2.clear();

            };

            for(const auto &cdat : form.urlData()){
                if(cdat.key.compare(0,13,"navitem_name_")==0 && cdat.key!="navitem_name_new")
                    changeItemName(cdat.key,cdat.value);
                else if(cdat.key.compare(0,12,"navitem_url_")==0 && cdat.key!="navitem_url_new")
                    changeItemUrl(cdat.key,cdat.value);
                else if(cdat.key.compare(0,13,"navitem_type_")==0 && cdat.key!="navitem_type_new")
                    changeItemType(cdat.key,cdat.value);
            }

            if(rem_itemid>=0){
                sql << "DELETE FROM navbar_items WHERE navbar_id='" << navid << "'AND id='" << rem_itemid << "'";
                Args->database[tid]->exec(sql,res);
                sql.clear();
            }

            if(!navname.empty()){
                sql << "UPDATE navbar SET name='" << sql.escaped(sbuf,navname.c_str()) << "' WHERE id='" << navid << "'";
                Args->database[tid]->exec(sql,res);
                sql.clear();
            }

            if(!container_id.empty()){
                sql << "UPDATE navbar SET container_id='" << sql.escaped(sbuf,container_id.c_str()) << "' WHERE id='" << navid << "'";
                Args->database[tid]->exec(sql,res);
                sql.clear();
            }


            if(!newitem_name.empty() && !newitem_url.empty() && !newitem_type.empty()){
                sql << "INSERT INTO navbar_items (name,url,navbar_id,type) VALUES('"
                    << sql.escaped(sbuf,newitem_name.c_str()) << "','" << sql.escaped(sbuf,newitem_url.c_str())
                    << "','" << navid << "'," << newitem_type.c_str() <<")";
                Args->database[tid]->exec(sql,res);
                sql.clear();
            }

            sql << "SELECT name,container_id from navbar WHERE id='" << navid << "' LIMIT 1";

            Args->database[tid]->exec(sql,res);

            sql.clear();

            // Build JSON
            json_object *jroot = json_object_new_object();
            json_object_object_add(jroot, "title", json_object_new_string(tr(_lang,"Edit Navigation").c_str()));

            // Nav: back link
            json_object *jnav = json_object_new_array();
            json_object *jback = json_object_new_object();
            json_object_object_add(jback, "label", json_object_new_string(tr(_lang,"Back to list").c_str()));
            json_object_object_add(jback, "url", json_object_new_string(Args->config->buildurl("settings/navbar").c_str()));
            json_object_array_add(jnav, jback);
            json_object_object_add(jroot, "nav", jnav);

            // Form
            json_object *jform = json_object_new_object();
            json_object_object_add(jform, "method", json_object_new_string("POST"));
            std::string formAction = Args->config->buildurl("settings/navbar/editnav?navid=") + std::to_string(navid);
            json_object_object_add(jform, "action", json_object_new_string(formAction.c_str()));

            // Top fields: name, container, hidden navid
            json_object *jfields = json_object_new_array();

            json_object *jfName = json_object_new_object();
            json_object_object_add(jfName, "name", json_object_new_string("navname"));
            json_object_object_add(jfName, "label", json_object_new_string(tr(_lang,"Name").c_str()));
            json_object_object_add(jfName, "type", json_object_new_string("text"));
            json_object_object_add(jfName, "value", json_object_new_string(res[0][0]));
            json_object_array_add(jfields, jfName);

            json_object *jfContainer = json_object_new_object();
            json_object_object_add(jfContainer, "name", json_object_new_string("navcontainer"));
            json_object_object_add(jfContainer, "label", json_object_new_string(tr(_lang,"HTML Container").c_str()));
            json_object_object_add(jfContainer, "type", json_object_new_string("text"));
            json_object_object_add(jfContainer, "value", json_object_new_string(res[0][1]));
            json_object_array_add(jfields, jfContainer);

            json_object *jfHidden = json_object_new_object();
            json_object_object_add(jfHidden, "name", json_object_new_string("navid"));
            json_object_object_add(jfHidden, "type", json_object_new_string("hidden"));
            json_object_object_add(jfHidden, "value", json_object_new_string(std::to_string(navid).c_str()));
            json_object_array_add(jfields, jfHidden);

            json_object_object_add(jform, "fields", jfields);

            // Form table: existing items + new item row
            sql << "select id,name,url from navbar_items WHERE navbar_id='" << navid << "' ORDER BY id";

            int n = Args->database[tid]->exec(sql,res);

            json_object *jftable = json_object_new_object();
            json_object *jftheaders = json_object_new_array();
            json_object_array_add(jftheaders, json_object_new_string(tr(_lang,"Item name").c_str()));
            json_object_array_add(jftheaders, json_object_new_string(tr(_lang,"Item URL").c_str()));
            json_object_array_add(jftheaders, json_object_new_string(tr(_lang,"Type").c_str()));
            json_object_array_add(jftheaders, json_object_new_string(tr(_lang,"Actions").c_str()));
            json_object_object_add(jftable, "headers", jftheaders);

            json_object *jftrows = json_object_new_array();
            for(int i=0; i<n; ++i){
                json_object *jrow = json_object_new_object();
                json_object *jrfields = json_object_new_array();

                std::string hname;
                libhtmlpp::HtmlEncode(res[i][1],hname);

                // name field
                json_object *jrfn = json_object_new_object();
                std::string fname = "navitem_name_" + std::string(res[i][0]);
                json_object_object_add(jrfn, "name", json_object_new_string(fname.c_str()));
                json_object_object_add(jrfn, "type", json_object_new_string("text"));
                json_object_object_add(jrfn, "value", json_object_new_string(hname.c_str()));
                json_object_array_add(jrfields, jrfn);

                // url field
                json_object *jrfu = json_object_new_object();
                std::string furl = "navitem_url_" + std::string(res[i][0]);
                json_object_object_add(jrfu, "name", json_object_new_string(furl.c_str()));
                json_object_object_add(jrfu, "type", json_object_new_string("text"));
                json_object_object_add(jrfu, "value", json_object_new_string(res[i][2]));
                json_object_array_add(jrfields, jrfu);

                // type select
                json_object *jrft = json_object_new_object();
                std::string ftype = "navitem_type_" + std::string(res[i][0]);
                json_object_object_add(jrft, "name", json_object_new_string(ftype.c_str()));
                json_object_object_add(jrft, "type", json_object_new_string("select"));
                json_object *joptions = json_object_new_array();
                json_object *joptLink = json_object_new_object();
                json_object_object_add(joptLink, "value", json_object_new_string("0"));
                json_object_object_add(joptLink, "label", json_object_new_string(tr(_lang,"link").c_str()));
                if(strcmp(res[i][2],"0")==0 || atoi(res[i][2])==0)
                    json_object_object_add(joptLink, "selected", json_object_new_boolean(1));
                json_object_array_add(joptions, joptLink);
                json_object *joptText = json_object_new_object();
                json_object_object_add(joptText, "value", json_object_new_string("1"));
                json_object_object_add(joptText, "label", json_object_new_string(tr(_lang,"text").c_str()));
                if(atoi(res[i][2])!=0)
                    json_object_object_add(joptText, "selected", json_object_new_boolean(1));
                json_object_array_add(joptions, joptText);
                json_object_object_add(jrft, "options", joptions);
                json_object_array_add(jrfields, jrft);

                json_object_object_add(jrow, "fields", jrfields);

                // remove action
                json_object *jractions = json_object_new_array();
                json_object *jremove = json_object_new_object();
                json_object_object_add(jremove, "label", json_object_new_string(tr(_lang,"remove").c_str()));
                std::string removeUrl = Args->config->buildurl("settings/navbar/editnav?navid=") + std::to_string(navid) + "&navitem_remove=" + std::string(res[i][0]);
                json_object_object_add(jremove, "url", json_object_new_string(removeUrl.c_str()));
                json_object_array_add(jractions, jremove);
                json_object_object_add(jrow, "actions", jractions);

                json_object_array_add(jftrows, jrow);
            }

            // New item row (empty)
            json_object *jnewrow = json_object_new_object();
            json_object *jnewfields = json_object_new_array();

            json_object *jnfn = json_object_new_object();
            json_object_object_add(jnfn, "name", json_object_new_string("navitem_name_new"));
            json_object_object_add(jnfn, "type", json_object_new_string("text"));
            json_object_object_add(jnfn, "value", json_object_new_string(""));
            json_object_array_add(jnewfields, jnfn);

            json_object *jnfu = json_object_new_object();
            json_object_object_add(jnfu, "name", json_object_new_string("navitem_url_new"));
            json_object_object_add(jnfu, "type", json_object_new_string("text"));
            json_object_object_add(jnfu, "value", json_object_new_string(""));
            json_object_array_add(jnewfields, jnfu);

            json_object *jnft = json_object_new_object();
            json_object_object_add(jnft, "name", json_object_new_string("navitem_type_new"));
            json_object_object_add(jnft, "type", json_object_new_string("select"));
            json_object *jnoptions = json_object_new_array();
            json_object *jnoptLink = json_object_new_object();
            json_object_object_add(jnoptLink, "value", json_object_new_string("0"));
            json_object_object_add(jnoptLink, "label", json_object_new_string(tr(_lang,"link").c_str()));
            json_object_object_add(jnoptLink, "selected", json_object_new_boolean(1));
            json_object_array_add(jnoptions, jnoptLink);
            json_object *jnoptText = json_object_new_object();
            json_object_object_add(jnoptText, "value", json_object_new_string("1"));
            json_object_object_add(jnoptText, "label", json_object_new_string(tr(_lang,"text").c_str()));
            json_object_array_add(jnoptions, jnoptText);
            json_object_object_add(jnft, "options", jnoptions);
            json_object_array_add(jnewfields, jnft);

            json_object_object_add(jnewrow, "fields", jnewfields);
            json_object_array_add(jftrows, jnewrow);

            json_object_object_add(jftable, "rows", jftrows);
            json_object_object_add(jform, "table", jftable);

            json_object_object_add(jform, "submit", json_object_new_string(tr(_lang,"save").c_str()));
            json_object_object_add(jroot, "form", jform);

            return jroot;
        }

        json_object* newNaviagtion(const int tid,libhttppp::HttpRequest &req){
            std::string navname,navcontainer;
            libhttppp::HttpForm form;
            form.parse(req);
            std::string _lang = getLang(*Args->database[tid]);

            for(const auto &cdat : form.urlData()){
                if(cdat.key=="navname")
                    navname=cdat.value;
                else if(cdat.key=="navcontainer")
                    navcontainer=cdat.value;
            }

            json_object *jroot = json_object_new_object();
            json_object_object_add(jroot, "title", json_object_new_string(tr(_lang,"New Navigation").c_str()));

            if(!navname.empty() && !navcontainer.empty()){
                dbpp::SQL sql;
                dbpp::DBResult res;
                std::vector<char> sbuf;

                sql << "INSERT INTO navbar (name,container_id) VALUES ('" << sql.escaped(sbuf,navname.c_str()) <<"','" <<  sql.escaped(sbuf,navcontainer.c_str()) << "')";

                Args->database[tid]->exec(sql,res);

                std::string msg = "Navigation " + navname + " created";
                json_object_object_add(jroot, "message", json_object_new_string(msg.c_str()));
                json_object_object_add(jroot, "message_type", json_object_new_string("success"));

                json_object *jnav = json_object_new_array();
                json_object *jback = json_object_new_object();
                json_object_object_add(jback, "label", json_object_new_string(tr(_lang,"Back to list").c_str()));
                json_object_object_add(jback, "url", json_object_new_string(Args->config->buildurl("settings/navbar").c_str()));
                json_object_array_add(jnav, jback);
                json_object_object_add(jroot, "nav", jnav);

                return jroot;
            }

            // Nav: back link
            json_object *jnav = json_object_new_array();
            json_object *jback = json_object_new_object();
            json_object_object_add(jback, "label", json_object_new_string(tr(_lang,"Back to list").c_str()));
            json_object_object_add(jback, "url", json_object_new_string(Args->config->buildurl("settings/navbar").c_str()));
            json_object_array_add(jnav, jback);
            json_object_object_add(jroot, "nav", jnav);

            // Form
            json_object *jform = json_object_new_object();
            json_object_object_add(jform, "method", json_object_new_string("POST"));
            json_object_object_add(jform, "action", json_object_new_string(Args->config->buildurl("settings/navbar/newnav").c_str()));

            json_object *jfields = json_object_new_array();

            json_object *jfName = json_object_new_object();
            json_object_object_add(jfName, "name", json_object_new_string("navname"));
            json_object_object_add(jfName, "label", json_object_new_string(tr(_lang,"Navigation name").c_str()));
            json_object_object_add(jfName, "type", json_object_new_string("text"));
            json_object_object_add(jfName, "value", json_object_new_string(""));
            json_object_array_add(jfields, jfName);

            json_object *jfContainer = json_object_new_object();
            json_object_object_add(jfContainer, "name", json_object_new_string("navcontainer"));
            json_object_object_add(jfContainer, "label", json_object_new_string(tr(_lang,"HTML Container name").c_str()));
            json_object_object_add(jfContainer, "type", json_object_new_string("text"));
            json_object_object_add(jfContainer, "value", json_object_new_string(""));
            json_object_array_add(jfields, jfContainer);

            json_object_object_add(jform, "fields", jfields);
            json_object_object_add(jform, "submit", json_object_new_string(tr(_lang,"create").c_str()));
            json_object_object_add(jroot, "form", jform);

            return jroot;
        }

        void GetSiteMap(const int tid,std::map<libhttppp::HttpUrl,std::chrono::year_month_day> &sitemap){
            return;
        }

        json_object* Settings(const int tid,libhttppp::HttpRequest &req,const std::string &sessionid){
            std::string _lang = getLang(*Args->database[tid]);
            std::string surl,curl=req.getRequestURL();
            size_t urlen = curl.length();
            size_t prelen = Args->config->buildurl("settings/navbar/").length();
            if(prelen < urlen){
                size_t sublen=urlen-prelen;

                for(size_t i =0; i<sublen; ++i){
                    if(curl[prelen+i]== '/'  || curl[prelen+i]== '?' ||  i+1==sublen){
                         surl=curl.substr(prelen,i-prelen);
                        break;
                    }
                }

                if(surl=="newnav"){
                    return newNaviagtion(tid,req);
                }else if(surl=="delnav"){
                    return delNavigation(tid,req);
                }else if(surl=="editnav"){
                    return editNavigation(tid,req);
                }
            }

            json_object *jroot = json_object_new_object();
            json_object_object_add(jroot, "title", json_object_new_string(tr(_lang,"Navbar Settings").c_str()));

            dbpp::SQL sql,sql2;
            dbpp::DBResult res,res2;
            sql << "select id,name,container_id from navbar";

            int n = Args->database[tid]->exec(sql,res);
            if(n>0){
                json_object *jtable = json_object_new_object();
                json_object *jheaders = json_object_new_array();
                json_object_array_add(jheaders, json_object_new_string(tr(_lang,"Name").c_str()));
                json_object_array_add(jheaders, json_object_new_string(tr(_lang,"Actions").c_str()));
                json_object_object_add(jtable, "headers", jheaders);

                json_object *jrows = json_object_new_array();
                for(int i=0; i<n; ++i){
                    json_object *jrow = json_object_new_object();
                    json_object *jcells = json_object_new_array();
                    json_object_array_add(jcells, json_object_new_string(res[i][1]));
                    json_object_object_add(jrow, "cells", jcells);

                    json_object *jactions = json_object_new_array();
                    json_object *jedit = json_object_new_object();
                    json_object_object_add(jedit, "label", json_object_new_string(tr(_lang,"edit").c_str()));
                    std::string editUrl = Args->config->buildurl("settings/navbar/editnav?navid=") + std::string(res[i][0]);
                    json_object_object_add(jedit, "url", json_object_new_string(editUrl.c_str()));
                    json_object_array_add(jactions, jedit);

                    json_object *jremove = json_object_new_object();
                    json_object_object_add(jremove, "label", json_object_new_string(tr(_lang,"remove").c_str()));
                    std::string removeUrl = Args->config->buildurl("settings/navbar/delnav?navid=") + std::string(res[i][0]);
                    json_object_object_add(jremove, "url", json_object_new_string(removeUrl.c_str()));
                    json_object_array_add(jactions, jremove);

                    json_object_object_add(jrow, "actions", jactions);
                    json_object_array_add(jrows, jrow);
                }
                json_object_object_add(jtable, "rows", jrows);
                json_object_object_add(jroot, "table", jtable);
            }

            json_object *jlinks = json_object_new_array();
            json_object *jnewLink = json_object_new_object();
            json_object_object_add(jnewLink, "label", json_object_new_string(tr(_lang,"New Navigation").c_str()));
            json_object_object_add(jnewLink, "url", json_object_new_string(Args->config->buildurl("settings/navbar/newnav").c_str()));
            json_object_array_add(jlinks, jnewLink);
            json_object_object_add(jroot, "links", jlinks);

            return jroot;
        }

        bool Controller(const int tid,libhttppp::HttpRequest &req,libhtmlpp::HtmlElement *page,const std::string &sessionid){
            return false;
        }
    };
};

EXPORT blogi::PluginApi* create() {
    return new blogi::Navbar();
}

EXPORT void destroy(blogi::PluginApi* p) {
    delete p;
}

