function Bookmarks() {
    this.init();


    this.cfg = {
        hasRefreshBtn: false,
        title: loc.text("bookmarks_title"),
        module: "Bookmarks",
        saveMethod: "POST"
    }



    this.domSettings = [

        { tag: "div", className: "bevel_section", innerHTML: loc.text("bookmarks_import"),
          style: {cursor: "pointer"},
          events: {onclick: "switchSection('section_import')"}
        },

        { tag: "div", className: "menu_panel", id: "section_import", display: false, align: "center", 
          innerHTML: "<iframe name='upload_frame' style='width: 0px; height: 0px; border: 0px'></iframe>",
          childs: [
            { tag: "form", method: "post", enctype: "multipart/form-data", action:"bookmarks.php", 
              target: "upload_frame",
              id: "upload_form",
              style: {padding: "0px", margin: "0px"},
              childs: [
                { tag: "input", type: "hidden", name: "MAX_FILE_SIZE", value:"500000"},
                { tag: "input", type: "hidden", id: "form_wid", name: "wid"},
                { tag: "input", type: "hidden", id: "form_user_id", name: "user_id"},
                { tag: "input", type: "file", name:"user_file", id: "user_file"},
                { tag: "input", type: "button", value: loc.text("bookmarks_btn_import"), id: "upload_submit_btn", events: {onclick: "uploadFile()"}}
              ]},
            { tag: "div", id: "import_msg", style: {width: "100%", display: "block"}, display: false}
          ]
        },

        { tag: "div", className: "bevel_section", innerHTML: loc.text("bookmarks_sec_delete"),
          style: {cursor: "pointer"},
          events: {onclick: "switchSection('section_delete')"}
        },
        { tag: "div", className: "menu_panel", id: "section_delete", display: false, align: "center",
          childs: [
            { tag: "input", type: "button", value: loc.text("bookmarks_btn_delete_all"), events: {onclick: "deleteBookmarks()"}}
          ]
        },


        { tag: "div", className: "bevel_section", innerHTML: loc.text("bookmarks_sec_add"), id: "add_bookmark",
          style: {cursor: "pointer"},
          events: {onclick: "switchSection('section_add')"}
        },

        { tag: "div", className: "menu_panel", id: "section_add", display: false, 
          childs: [
            { tag: "div", className: "menu_panel", innerHTML: loc.text("bookmarks_inp_title"),
              childs: [
                { tag: "input", type: "text", size: "30", id: "select_title"}
              ]
            },
            { tag: "div", className: "menu_panel", innerHTML: loc.text("bookmarks_inp_url"),
              childs: [
                { tag: "input", type: "text", size: "30", id: "select_url"}
              ]
            },              
            { tag: "div", className: "menu_panel", innerHTML: loc.text("bookmarks_inp_tags"),
              childs: [
                { tag: "input", type: "text", size: "30", id: "select_tags"}
              ]
            },              
            { tag: "div", className: "menu_panel", align: "center",
              childs: [
                { tag: "input", type: "button", value: loc.text("btn_save"), events: {onclick: "processAdd()"}}
              ]
            }
          ]
        }
    ];


    this.domContent = [
        { tag: "div", className: "bevel_section", innerHTML: loc.text("bookmarks_sec_edit"), id: "edit_bookmark", display: false, 
          style: {cursor: "pointer"},
          events: {onclick: "switchSection('section_edit')"}
        },

        { tag: "div", className: "menu_panel", id: "section_edit", display: false, 
          childs: [
            { tag: "div", className: "menu_panel", innerHTML: loc.text("bookmarks_inp_title"),
              childs: [
                { tag: "input", type: "text", size: "30", id: "edit_title"}
              ]
            },
            { tag: "div", className: "menu_panel", innerHTML: loc.text("bookmarks_inp_url"),
              childs: [
                { tag: "input", type: "text", size: "30", id: "edit_url"}
              ]
            },              
            { tag: "div", className: "menu_panel", innerHTML: loc.text("bookmarks_inp_tags"),
              childs: [
                { tag: "input", type: "text", size: "30", id: "edit_tags"}
              ]
            },              
            { tag: "div", className: "menu_panel", align: "center",
              childs: [
                { tag: "input", type: "button", value: loc.text("btn_save"), events: {onclick: "processUpdate()"}}
              ]
            }
          ]
        },

        { tag: "div", className: "bevel_section", innerHTML: loc.text("bookmark_sec_tags"),
          style: {cursor: "pointer"},
          events: {onclick: "switchSection('section_tags')"}},

        { tag: "div", className: "menu_panel", id: "section_tags", display: false, align: "left"},

        { tag: "hr", width: "100%"},

        { tag: "div", className: "menu_panel", id: "bookmarks", align: "left"}
    ]

    this.defaultProfile["title"] = loc.text("bookmarks_title");
    this.defaultProfile["tags"] = ['default']; 
    this.defaultProfile["bookmarks"] = []; 

    this.activeTag = 0;

    this.onBuildInterface = function() {
        this.buildDomModel(this.elements.settings, this.domSettings);        
        this.buildDomModel(this.elements.content, this.domContent);        
        this.applyTag(0);
        this.elements.form_wid.value = this.id;
        this.elements.form_user_id.value = auth.user.id;
    }


    this.onShowSettings = function() {
        this.closeEdit();
    }


    this.settingsSetTitle = function() {
        this.profile.title = trim(this.elements.input_title.value);
        this.setTitle(this.profile.title + ": "+ this.profile.tags[this.activeTag]);
        this.save();
    }

    this.switchSection = function(sid) {
        if(this.elements[sid].style.display == 'none') {
            showEl(this.elements[sid]);
        } else {
            hideEl(this.elements[sid]);
        }
    }



    // importing
    this.uploadFile = function() {
        if(trim(this.elements.user_file.value)!="") {
            showEl(this.elements.import_msg);
            this.elements.import_msg.innerHTML = loc.text("bookmarks_msg_import");
            hideEl(this.elements.upload_submit_btn);
            this.elements.upload_form.submit();
        }
    }


    this.importError = function() {
        showEl(this.elements.upload_submit_btn);
        this.elements.import_msg.innerHTML = loc.text("bookmarks_msg_import_error");
    }

    this.importFromUrl = function(file) {
        if(file) {
            xmlRequest.send("var/tmp/"+file, this, "parseBookmarks");
            this.tmpFile = file;
        } else {
            showEl(this.elements.upload_submit_btn);
            this.elements.import_msg.innerHTML = loc.text("bookmarks_msg_import_error");
        }
    }


    this.parseBookmarks = function(response) {
        showEl(this.elements.upload_submit_btn);

        if(response.responseText) {
            var tmp = document.createElement("span");
            tmp.innerHTML = response.responseText.replace(/\<p\>/g, '').replace(/\r\n/g, '').replace(/>\s*</g, '><').replace(/<DT>/g, "").replace(/<DD>/g, '');
            var data = XMLParser.parseBookmarks(tmp);

            for(var i=0; i<data.length; i++) {
                this.addBookmark(data[i].title, data[i].url, data[i].tags);
            }
            this.renderTags();
            showEl(this.elements.section_tags);
            this.applyTag(this.activeTag);
            this.save();

            if(this.tmpFile) {
                request.send({act: "delete", file: this.tmpFile}, this);
            }

            hideEl(this.elements.import_msg);
            hideEl(this.elements.section_import);
            this.hideSettings();
            return;
        }

        this.elements.import_msg.innerHTML = loc.text("bookmarks_msg_import_error");
    }




    this.editBookmarkId = null;
    this.closeEdit = function() {
        if(this.editBookmarkId != null) {
            hideEl(this.elements.section_edit);
            hideEl(this.elements.edit_bookmark);
            this.isEditOpen = null;
        }
    }

    this.openEdit = function(id) {
        this.editBookmarkId = id;

        var tags = [];
        for(var i = 0; i < this.profile.bookmarks[id].tags.length; i++) {
            tags.push(this.profile.tags[this.profile.bookmarks[id].tags[i]])
        }
        this.elements.edit_title.value = this.profile.bookmarks[id].title;
        this.elements.edit_url.value = this.profile.bookmarks[id].url;
        this.elements.edit_tags.value = tags.join(", ");

        showEl(this.elements.section_edit);
        showEl(this.elements.edit_bookmark);
        hideEl(this.elements.settings);
    }


    this.processUpdate = function() {
        if(this.editBookmarkId != null) {
            var title = trim(this.elements.edit_title.value);
            var url = trim(this.elements.edit_url.value);
            if(title != "" && url != "") {
                this.updateBookmark(this.editBookmarkId, title, url, trim(this.elements.edit_tags.value));

                this.applyTag(this.activeTag);
                this.save();
            }
        }
        this.closeEdit();
    }




    this.deleteBookmarks = function() {
        this.profile.bookmarks = this.defaultProfile["bookmarks"];
        this.profile.tags = this.defaultProfile["tags"];
        this.applyTag(0);
    }



    this.processAdd = function() { 
        var title = trim(this.elements.select_title.value);
        var url = trim(this.elements.select_url.value);
        if(title != "" && url != "") {
            this.closeEdit();
            this.addBookmark(title, url, trim(this.elements.select_tags.value));
            this.save();
            this.applyTag(this.activeTag);

            this.elements.select_title.value = '';
            this.elements.select_url.value = '';
            this.elements.select_tags.value = '';
        }
    }




    this.renderTags = function() {
        this.elements.section_tags.innerHTML = '';
        for(var t=0; t<this.profile.tags.length; t++) {
            if(this.profile.tags[t] != undefined) {
                if(this.activeTag != t) {
                    this.buildDomModel(this.elements.section_tags,
                        { tag: "a", 
                          href: "void", events: { onclick: "applyTag("+t+")"}, 
                          innerHTML: this.profile.tags[t],
                          style: { margin: "4px"}
                        });
                } else {
                    this.buildDomModel(this.elements.section_tags,
                        { tag: "span", innerHTML: this.profile.tags[t],
                          style: { margin: "4px"}
                        });
                }
            }
        }
    }





    this.applyTag = function(tagId) {
        this.closeEdit();
        this.activeTag = tagId;
        this.setTitle(this.profile.title + ": "+ this.profile.tags[tagId]);

        var list = this.getBookmarksByTagId(tagId);

        this.elements.bookmarks.innerHTML = '';
        for(var i = 0; i<list.length; i++) {
            var itemDom = { tag: "div", className: "menu_panel", id: "item"+list[i],
                            childs: [
                              createTableDom([ {content: {tag: "a", id: "item_title"+list[i], sysHref: this.profile.bookmarks[list[i]].url, target: "_blank", innerHTML: this.profile.bookmarks[list[i]].title}, width: "95%"},
                                               {content: createButtonDom(false, "openEdit("+list[i]+")", "static/client/edit.gif"), width: "1%"},
                                               {content: createButtonDom(false, "deleteItem("+list[i]+")", "static/client/delete_link.gif"), width: "1%"}
                                             ], "95%")
                            ]
                          }
            this.buildDomModel(this.elements.bookmarks, itemDom);
        }

        this.renderTags();
    }


    this.deleteItem = function(id) {
        if(confirm(loc.text("bookmarks_delete_prompt", this.profile.bookmarks[id].title))) {
            this.closeEdit();
            this.deleteBookmark(id);
            if(this.profile.tags[this.activeTag]) {
                this.applyTag(this.activeTag);
            } else {
                this.applyTag(0);
            }
            this.save();
        }
    }



    this.updateBookmark = function(id, title, url, tags) {
        this.deleteBookmark(id);
        this.addBookmark(title, url, tags);    
    }


    this.addBookmark = function(title, url, tagsData) {
        var newBookmark = { title: title, 
                            url: url, 
                            tags: [] };

        if(typeof(tagsData) == "string") {
            var tags = tagsData!= "" ? tagsData.split(",") : false;
        } else {
            var tags = tagsData;
        }

        if(tags) {
            for(var i = 0; i<tags.length; i++) {
                tags[i] = trim(tags[i]);
                var tn = arraySearch(tags[i], this.profile.tags)
                if(tn != undefined) {
                    newBookmark.tags.push(tn);
                } else {
                    var idx = arrayFirstFree(this.profile.tags);
                    this.profile.tags[idx] = tags[i];
                    newBookmark.tags.push(idx);
                }
            }
        } else {
            newBookmark.tags = [0];
        }

        this.activeTag = newBookmark.tags[0];
        this.profile.bookmarks[arrayFirstFree(this.profile.bookmarks)] = newBookmark;
    }



    this.deleteBookmark = function(id) {
        var tags = this.profile.bookmarks[id].tags;
        for(var i=0; i<tags.length; i++) {
            if(tags[i] != 0) {
                var count = 0;
                for(var j=0; j<this.profile.bookmarks.length; j++) {
                    if(this.profile.bookmarks[j] && arraySearch(tags[i], this.profile.bookmarks[j].tags) != undefined) {
                        count++;
                    }
                }
                if(count<2) {
                    this.profile.tags[tags[i]] = undefined;
                }
            }
        }
        this.profile.bookmarks[id] = undefined;
    }


    this.getBookmarksByTagId = function(tagId) {
        var res = [];

        for(var i=0; i<this.profile.bookmarks.length; i++) {
            if(this.profile.bookmarks[i] && 
               this.profile.bookmarks[i].tags != undefined &&
               arraySearch(tagId, this.profile.bookmarks[i].tags) != undefined) {
                res.push(i);
            }
        }
        return res;
    }

 
}
Bookmarks.prototype = new Widget();