function context_menu(map){
    _debug('context_menu');
    
    this.on = false;
    this.map = map || [];
    this.container;
    this.parent = document.body;
    this.menu_windows = [];
    this.cur_win;
    
    if (arguments.length > 1){
        if (arguments[1].hasOwnProperty('parent')){
            this.parent = arguments[1].parent;
        }
    }
}

context_menu.prototype.destroy_container = function(){
    _debug('context_menu.destroy_container');
    
    _debug('remove DOM element - container');
    
    try{
        if (this.container){
            this.container.parentNode.removeChild(this.container);
        }
    }catch(e){
        _debug(e);
    }
};

context_menu.prototype.reset = function(){
    _debug('context_menu.reset');
    
    if (this.on){
        //this.hide();
    }
    
    this.destroy_container();
    
    //delete this.map;
    this.menu_windows = [];
};

context_menu.prototype.show = function(){
    _debug('context_menu.show');
    
    _debug('this.map.length', this.map.length);
    
    try{
        if (this.map.length > 0){
            this.on = true;
            this.container.show();
            this.container.style.height = 0;
            this.set_active_row();
        }
    }catch(e){
        _debug(e);
    }
};

context_menu.prototype.hide = function(){
    _debug('context_menu.hide');
    
    this.on = false;
    this.container.hide();
    this.set_passive_row();
    
    try{
        for (var i=0; i < this.menu_windows.length; i++){
            //if (!this.menu_windows[i].dom_obj.isHidden()){
                
                if (!this.menu_windows[i].main){
                    this.menu_windows[i].dom_obj.hide();
                    this.cur_win = this.menu_windows[i];
                    this.set_passive_row();
                    this.cur_win.cur_row = 0;
                }
            //}
        }
        
        var idx = this.menu_windows.getIdxByVal('main', true);
        this.cur_win = this.menu_windows[idx];
        this.set_passive_row();
        this.cur_win.cur_row = 0;
        this.cur_win.dom_obj.setClass('con_menu_main_active');
        
    }catch(e){
        _debug(e);
    }
    
};

/**
 * @param {Array} map = [{'title' : String, 'cmd' : String | Array map, 'type' : 'switch|options'}]
 * @param {Object}
 *
 */
context_menu.prototype.construct = function(map){
    _debug('context_menu.construct', map);
    
    this.map = map || [];
    
    this.reset();
    
    //if (!this.container){
        this.container = create_block_element('context_menu_container', this.parent);
        this.container.hide();
    //}
    
    var dom_obj = create_block_element('con_menu_main_active', this.container);
    
    var main_table = document.createElement("table");
    this.main_table = main_table;
    
    /* MAIN MENU TOP ROW */
    var main_top_tr = document.createElement("tr");
    
    var main_top_left_td = document.createElement("td");
    main_top_left_td.setClass('v_menu1_top_l');
    main_top_tr.appendChild(main_top_left_td);
    
    var main_top_right_td = document.createElement("td");
    main_top_right_td.setClass('v_menu1_top_r');
    main_top_tr.appendChild(main_top_right_td);
    
    main_table.appendChild(main_top_tr);
    /* END MAIN MENU TOP ROW */
    
    /* MAIN MENU CENTER ROW */
    var main_center_tr = document.createElement("tr");
    
    var main_center_td = document.createElement("td");
    main_center_tr.appendChild(main_center_td);
    
    var main_container_table = document.createElement("table");
    main_container_table.setClass('con_menu_container');
    main_center_td.appendChild(main_container_table);
    
    for (var i=0; i<map.length; i++){
        var container_tr = document.createElement("tr");
        map[i].dom_obj = document.createElement("td");
        container_tr.appendChild(map[i].dom_obj);
        main_container_table.appendChild(container_tr);
        
        if (i==0){
            map[i].dom_obj.setClass('active');
        }
        
        map[i].title_dom_obj = create_inline_element('', map[i].dom_obj);
        
        map[i].title_dom_obj.innerHTML = map[i].title;
        
        if (typeof(map[i].cmd) == 'object'){
            map[i].sub_dom_obj = this.construct_sub_menu(i, map[i].cmd, map[i].type);
        }
    }
    
    this.cur_win = {
        "win_idx"  : this.menu_windows.length,
        "parent_win" : -1,
        "main"     : true,
        "from_row" : -1,
        "dom_obj"  : dom_obj,
        "cur_row"  : 0,
        "prev_row" : 0,
        "map"      : map
    };
    
    this.menu_windows.push(this.cur_win);
    
    main_table.appendChild(main_center_tr);
    
    var main_center_right_cell = document.createElement("td");
    main_center_right_cell.setClass('v_menu1_center_r');
    main_center_right_cell.innerHTML = '&nbsp;';
    
    main_center_tr.appendChild(main_center_right_cell);
    /* END MAIN MENU CENTER ROW */
    
    /* MAIN MENU BOTTOM ROW */
    var main_bottom_tr = document.createElement("tr");
    
    var main_bottom_left_td = document.createElement("td");
    main_bottom_left_td.setClass('v_menu1_bottom_l');
    main_bottom_tr.appendChild(main_bottom_left_td);
    
    var main_bottom_right_td = document.createElement("td");
    main_bottom_right_td.setClass('v_menu1_bottom_r');
    main_bottom_tr.appendChild(main_bottom_right_td);
    
    main_table.appendChild(main_bottom_tr);
    /* END MAIN MENU BOTTOM ROW */
    
    dom_obj.appendChild(main_table);
};

context_menu.prototype.construct_sub_menu = function(from_row, map_item, type){
    
    var sub_menu = create_block_element('sub_con_menu', this.container);
    
    if (from_row != 0){
        sub_menu.hide();
    }
    
    var top = from_row*30-5;
    
    sub_menu.offsetY(top);
    
    var sub_table = document.createElement("table");
    
    /* SUB MENU TOP ROW */
    var sub_top_tr = document.createElement("tr");
    
    var sub_top_left_td = document.createElement("td");
    sub_top_left_td.setClass('v_menu2_top_l');
    sub_top_tr.appendChild(sub_top_left_td);
    
    var sub_top_right_td = document.createElement("td");
    sub_top_right_td.setClass('v_menu2_top_r');
    sub_top_tr.appendChild(sub_top_right_td);
    
    sub_table.appendChild(sub_top_tr);
    /* END SUB MENU TOP ROW */
    
    /* SUB MENU CENTER ROW */
    var sub_center_tr = document.createElement("tr");
    
    var sub_center_left_cell = document.createElement("td");
    sub_center_left_cell.setClass('v_menu2_center_l');
    sub_center_left_cell.innerHTML = '&nbsp;';
    sub_center_tr.appendChild(sub_center_left_cell);
    
    var sub_center_td = document.createElement("td");
    sub_center_tr.appendChild(sub_center_td);
    
    var sub_container_table = document.createElement("table");
    sub_container_table.setClass('sub_menu_container');
    sub_center_td.appendChild(sub_container_table);
    
    for (var i=0; i<map_item.length; i++){
        var container_tr = document.createElement("tr");
        map_item[i].dom_obj = document.createElement("td");
        container_tr.appendChild(map_item[i].dom_obj);
        sub_container_table.appendChild(container_tr);
        
        if (i==0){
            //map_item[i].dom_obj.setClass('active');
        }
        
        map_item[i].space = create_block_element('space', map_item[i].dom_obj);
        map_item[i].space.innerHTML = '&nbsp;';
        map_item[i].bull  = create_block_element('bull', map_item[i].dom_obj);
        map_item[i].bull.innerHTML = '&bull;';
        map_item[i].bull.hide();
        
        map_item[i].title_dom_obj = create_inline_element('', map_item[i].dom_obj);
        
        if (map_item[i].hasOwnProperty('active')){
            if (map_item[i].active && (this.map[from_row].type == 'switch' || this.map[from_row].type == 'options')){
                map_item[i].bull.show();
                map_item[i].space.hide();
            }
        }
        
        map_item[i].title_dom_obj.innerHTML = map_item[i].title;
    }
    
    this.menu_windows.push(
    {
        "win_idx"  : this.menu_windows.length,
        "parent_win" : 0,
        "main"     : false,
        "from_row" : from_row,
        "dom_obj"  : sub_menu,
        "cur_row"  : 0,
        "prev_row" : 0,
        "map"      : map_item,
        "type"     : type
    });
    
    sub_table.appendChild(sub_center_tr);
    /* END SUB MENU CENTER ROW */
    
    /* SUB MENU BOTTOM ROW */
    var sub_bottom_tr = document.createElement("tr");
    
    var sub_bottom_left_td = document.createElement("td");
    sub_bottom_left_td.setClass('v_menu2_bottom_l');
    sub_bottom_tr.appendChild(sub_bottom_left_td);
    
    var sub_bottom_right_td = document.createElement("td");
    sub_bottom_right_td.setClass('v_menu2_bottom_r');
    sub_bottom_tr.appendChild(sub_bottom_right_td);
    
    sub_table.appendChild(sub_bottom_tr);
    /* END SUB MENU BOTTOM ROW */
    
    sub_menu.appendChild(sub_table);
    
    return sub_menu;
};

context_menu.prototype.bind = function(){
    
    this.shift_row.bind(key.UP,   this, -1);
    this.shift_row.bind(key.DOWN, this,  1);
    
    this.goto_sub_menu.bind(key.RIGHT, this);
    
    this.action.bind(key.OK, this);
    
    this.goto_main_menu.bind(key.LEFT, this);
    
    this.hide.bind(key.EXIT, this).bind(key.NULL, this).bind(key.WEB, this).bind(key.AUDIO, this);
};

context_menu.prototype.goto_sub_menu = function(){
    if (this.cur_win.main){
        
        var idx = this.menu_windows.getIdxByVal('from_row', this.cur_win.cur_row);
        
        this.cur_win.dom_obj.setClass('con_menu_main_passive');
        
        this.cur_win = this.menu_windows[idx];
        this.set_active_row();
    }
};

context_menu.prototype.goto_main_menu = function(){
    if (!this.cur_win.main){
        
        this.set_passive_row();
        
        var idx = this.menu_windows.getIdxByVal('main', true);
        
        this.cur_win = this.menu_windows[idx];
        
        this.cur_win.dom_obj.setClass('con_menu_main_active');
    }
};

context_menu.prototype.action = function(){
    _debug('context_menu.action');
    
    if (this.cur_win.type == 'switch'){

        this.reset_switch(this.cur_win.cur_row);
        
    }else if(this.cur_win.type == 'options'){
        this.set_active_option(this.cur_win.cur_row);
    }
    
    _debug('title', this.cur_win.map[this.cur_win.cur_row].title);
    _debug('cmd', this.cur_win.map[this.cur_win.cur_row].cmd);
    
    try{
        this.cur_win.map[this.cur_win.cur_row].cmd();
    }catch(e){
        _debug(e);
    }

    this.hide();
};

context_menu.prototype.set_active_option = function(row){
    
    this.cur_win.map[row].space.hide();
    this.cur_win.map[row].bull.show();
};

context_menu.prototype.reset_switch = function(exept){
    for (var i = 0; i < this.cur_win.map.length; i++){
        
        if (i != exept){
            this.cur_win.map[i].space.show();
            this.cur_win.map[i].bull.hide();
        }else{
            this.cur_win.map[i].space.hide();
            this.cur_win.map[i].bull.show();
        }
        
    }
};

context_menu.prototype.shift_row = function(dir){
    _debug('context_menu.shift_row', dir);
    
    this.cur_win.prev_row = this.cur_win.cur_row;
    
    if (dir > 0){
        if (this.cur_win.cur_row < this.cur_win.map.length - 1){
            this.cur_win.cur_row++;
        }else{
            this.cur_win.cur_row = 0;
        }
    }else{
        if (this.cur_win.cur_row > 0){
            this.cur_win.cur_row--;
        }else{
            this.cur_win.cur_row = this.cur_win.map.length - 1;
        }
    }
    
    this.set_active_row();
};

context_menu.prototype.set_active_row = function(){
    _debug('context_menu.set_active_row');
    
    try{
        this.cur_win.map[this.cur_win.prev_row].dom_obj.delClass();
        this.cur_win.map[this.cur_win.cur_row].dom_obj.setClass('active');
        
        if (this.cur_win.main){
            this.cur_win.map[this.cur_win.prev_row].sub_dom_obj.hide();
            this.cur_win.map[this.cur_win.cur_row].sub_dom_obj.moveX(this.cur_win.dom_obj.childNodes[0].offsetWidth);
            this.cur_win.map[this.cur_win.cur_row].sub_dom_obj.show();
        }
        
    }catch(e){
        _debug(e)
    }
};

context_menu.prototype.set_passive_row = function(){
    _debug('context_menu.set_passive_row');
    
    try{
        this.cur_win.map[this.cur_win.cur_row].dom_obj.delClass();
    }catch(e){
        _debug(e)
    }
};

context_menu.prototype.set_x_offset = function(x){
    _debug('context_menu.set_x_offset', x);
    
    x = parseInt(x);
    
    if(this.container){
        this.container.style.left = parseInt(x) + 'px';
    }
};

context_menu.prototype.set_y_offset = function(y){
    _debug('context_menu.set_y_offset', y);
    
    y = parseInt(y);
    
    if(this.container){
        this.container.style.top = parseInt(y) + 'px';
    }
};

context_menu.prototype.set_z_index = function(z){
    _debug('context_menu.set_z_index', z);
    
    z = parseInt(z);
    
    if(this.container){
        this.container.style.zIndex = parseInt(z);
    }
};

loader.next();