function get_graphic_scale()
  local width, height = diretheme.get_screen();
  local max_scale_x = width / 1920;
  local max_scale_y = height / 1440;
  return math.min(max_scale_x, max_scale_y);
end;

function get_font_scale()
  local rval = prefs.font_scale;
  if not rval then
    rval = 100;
  end;
  return rval
end;

function get_inventory_font_scale()
  local rval = prefs.inventory_scale;
  if not rval then
    rval = get_font_scale();
  end;
  return rval
end;

function get_cursor_scale()
  return prefs.cursor_scale or 100;
end;

function set_theme()
  if instead.tiny then
    return
  end;
  
  local text_align = 'justify';
  if prefs.text_alignment == 2 then
    text_align = 'left';
  end;
  
  local hpadding, vpadding = 0, 0;
  if prefs.text_padding == 2 then
    hpadding, vpadding = 58, 29;
  end;
  
  local interval = '1.0';
  if prefs.text_interval == 2 then
    interval = '1.5';
  end;
  
  local width, height = diretheme.get_screen();
  
  local images = {
    {2560, 1920, 1440, '1440'},
    {1365, 1024, 768, '768'},
    {1067, 800, 600, '600'},
    {853, 640, 480, '480'},
  }
  
  local imgw = images[1][1];
  local imgwmin = images[1][2];
  local imgh = images[1][3];
  image_suffix = images[1][4];
  for _, image in ipairs(images) do
    if image[2] < width and image[3] < height then
      break;
    end;
    imgw = image[1];
    imgwmin = image[2];
    imgh = image[3];
    image_suffix = image[4];
  end;
  
  diretheme.set_canvas({
      rmin = 4 / 3,
      rmax = 16 / 9,
      ax = 0,
      lx = 0,
      ay = 0
  });
  local c = diretheme.get_canvas();
  
  local scale = diretheme.get_scale();
  local max_scale_x = c.w / imgwmin;
  local max_scale_y = c.h / imgh;
  image_scale = math.min(max_scale_x, max_scale_y);
  
  local graphic_scale = get_graphic_scale();
  
  
  local font_scale = get_font_scale() / 100;
  local font_size = math.floor(34 * graphic_scale * font_scale);
  if font_size < 7 then
    font_size = 7;
  end;
  local inv_scale = get_inventory_font_scale() / 100;
  local inv_size = math.floor(34 * graphic_scale * inv_scale);
  if inv_size < 7 then
    inv_size = 7;
  end;
  
  local bg = pixels.new(width, height);
  local s = pixels.new('images/bg_' .. image_suffix .. '_full.png');
  if image_scale ~= 1 then
    s = s:scale(image_scale, image_scale, 1)
  end;
  s:copy(bg, math.floor((width - c.w) / 2), math.floor((height - c.h) / 2));
  
  local up = pixels.new('images/scroll_up_' .. image_suffix .. '.png');
  local down = pixels.new('images/scroll_down_' .. image_suffix .. '.png');
  if image_scale ~= 1 then
    up = up:scale(image_scale, image_scale, 1)
    down = down:scale(image_scale, image_scale, 1);
  end;
  local upw, uph = up:size();
  local downw, downh = down:size();
  
  diretheme.set_background('#000000', 1, bg, {
    mode = 3
  });
  diretheme.set_text_area({
    rect = {
      ax = -1,
      ay = -1,
      lx = 188,
      ty = 110,
      wmax = 1056,
      wmin = 1056,
      hmin = 1220,
      hmax = 1220
    };
    height = interval;
    align = text_align;
    contentrect = {
      lx = hpadding,
      rx = hpadding,
      ty = vpadding,
      by = vpadding,
      wf = prefs.text_width / 100
    };
    text = {
      size = font_size,
      noscale = true,
    };
    up = up;
    down = down;
    uppos = {
      x = math.floor((-46 - (100 - prefs.text_width) * 2.2 - hpadding / scale) * graphic_scale) - upw,
      y = math.floor(177 * graphic_scale);
      ax = -1;
      ay = -1;
    };
    downpos = {
      x = math.floor((-46 - (100 - prefs.text_width) * 2.2 - hpadding / scale) * graphic_scale) - downw,
      y = math.floor(-131 * graphic_scale);
      ax = -1;
      ay = 1;
    };
  });

  local invup = pixels.new('images/inv_scroll_up_' .. image_suffix .. '.png');
  local invdown = pixels.new('images/inv_scroll_down_' .. image_suffix .. '.png');
  
  if image_scale ~= 1 then
    invup = invup:scale(image_scale, image_scale, 1);
    invdown = invdown:scale(image_scale, image_scale, 1)
  end;
  
  local invupw, invuph = invup:size();
  local invdownw, invdownh = invdown:size();

  diretheme.set_inventory_area({
    rect = {
      ax = -1,
      ay = -1,
      lx = 1388,
      ty = 142,
      hmin = 545,
      hmax = 545,
      wmin = 435,
      wmax = 435
    };
    text = {
      size = inv_size,
      noscale = true
    };
    up = invup;
    uppos = {
      x = math.round((435 * graphic_scale - invupw) / 2),
      y = -invuph - 2 * graphic_scale;
      ax = -1;
      ay = -1;
    };
    down = invdown;
    downpos = {
      x = math.round((435 * graphic_scale - invdownw) / 2),
      y = invdownh + 2 * graphic_scale;
      ax = -1;
      ay = 1;
    };
  });
  
  local button = pixels.new('images/menu_' .. image_suffix .. '.png');
  if image_scale ~= 1 then
    button = button:scale(image_scale, image_scale, 1);
  end;
  local buttonw, buttonh = button:size();

  diretheme.set_menu({
      buttonrect = {
        noscale=true,
        ax = -1,
        ay = -1,
        wmin=buttonw,
        wmax=buttonw,
        hmin=buttonh,
        hmax=buttonh,
        lx = math.floor(1616 * graphic_scale),
        ty = math.floor(1358 * graphic_scale),
      };
      button = {
        image = button;
        options = {mode = 1};
      };
      text = {
        size = font_size,
        noscale = true
      },
  });
  
  theme.set('scr.gfx.scale', 1);
  theme.set('scr.gfx.pad', font_size);
  set_cursor();
end;

declare {
  image_suffix = '1440';
  image_scale = 1;
}

global {
  selected_cursor = 'choose';
}

function set_cursor(cr)
  if instead.tiny then
    return
  end;
  
  if cr then
    selected_cursor = cr;
  end;
  local cs = math.round(get_cursor_scale() / 100);
  local pxln = pixels.new('images/cursor_' .. selected_cursor .. '_normal.png');
  local pxlu = pixels.new('images/cursor_' .. selected_cursor .. '_use.png');
  
  if cs ~= 1 then
    pxln = pxln:scale(cs, cs, false);
    pxlu = pxlu:scale(cs, cs, false);
  end;
  
  diretheme.set_cursor({
      normal = pxln;
      use = pxlu;
  });
end;

function get_screen_metrics()
  local w, h = diretheme.get_screen();
  
  local wsmax = w / 640;
  local smax = h / 480;
  if wsmax < smax then
    smax = wsmax;
  end;

  if smax < 1 then
    smax = 1;
  end;

  return 800, 800, math.floor(smax * 2);
end;

room {
  nam = 'back';
  onenter = function()
    walkout();
    return false;
  end;
}

room {
  nam = 'system_settings';
  onenter = function()
    instead.menu('settings');
    return false;
  end;
}

room {
  nam = 'settings';
  nosave = true;
  noautosave = true;
  noinv = true;
  notime = true;
  disp = translate('menu_locale', 'settings');
  theme = 'menu';
  way = {
    path {translate('common_locale', 'back'), 'back'};
    path {translate('menu_locale', 'system_settings'), 'system_settings'};
  };
}:with {
  obj {
    nam = '#language';
    dsc = function(s)
      local l = translate_now("menu_locale", 'auto_option');
      
      pn(fmt.b(translate_now("menu_locale", 'language')));
      
      local t;
      if get_language_saved() == '' then
        t = l;
      else
        t = '{#l_auto|'.. l .. '}';
      end;
      
      for i, language in ipairs(get_language_list()) do
        if get_language_saved() == language[1] then
          t = t .. ' | ' .. language[2];
        else
          t = t .. ' | ' .. '{@set_language ' .. language[1] .. '|' .. language[2] .. '}';
        end;
      end;
    
      pn(t .. '^')
    end;
  }: with {
    obj {
      nam = '#l_auto';
      act = function(s)
        set_language('');
        walk(here());
      end;
    };
  };
  obj {
    nam = '#cursor_scale';
    dsc = function(s)
      if theme.name() ~= '.' then
        return
      end;
      
      local cursor_scale = get_cursor_scale();
      
      pn(fmt.b(translate_now("menu_locale", 'cursor_scale')) .. ' {[' .. translate_now("menu_locale", 'auto_option') .. ']}')
    
      local t = '';
      
      if cursor_scale > 100 then
        t = t .. '{#cursor_less|<<} ';
      else
        t = t .. '<< ';
      end;

      local l = translate_now("menu_locale", 'auto_option') .. ' (' .. tostring(cursor_scale) .. '%)';
      
      if prefs.cursor_scale then
        l = tostring(cursor_scale) .. '%';
      end;

      t = t .. l;

      local w, h, smax = get_screen_metrics();
    
      if cursor_scale < smax * 100 then
        t = t .. ' {#cursor_more|>>}';
      else
        t = t .. ' >>';
      end;
    
      pn(t .. '^');
    end;
    act = function(s)
      prefs.cursor_scale = false;
      prefs:store();
    
      set_theme();
      walk(here());
    end;
  }: with {
    obj {
      nam = '#cursor_less';
      act = function(s)
        prefs.cursor_scale = get_cursor_scale() - 100;
        prefs:store();
    
        set_theme();
        walk(here());
      end;
    };
    obj {
      nam = '#cursor_more';
      act = function(s)
        prefs.cursor_scale = get_cursor_scale() + 100;
        prefs:store();
    
        set_theme();
        walk(here());
      end;
    };
  };
  obj {
    nam = '#font_scale';
    dsc = function(s)
      if theme.name() ~= '.' then
        return
      end;
      
      local graphic_scale = get_graphic_scale();
      local font_scale = get_font_scale();
        
      pn(fmt.b(translate_now("menu_locale", 'font_scale')) .. ' {[' .. translate_now("menu_locale", 'auto_option') .. ']}');
    
      local t = '';
    
      if font_scale > 50 then
        t = t .. '{#f_less|<<} ';
      else
        t = t .. '<< ';
      end;
    
      if prefs.font_scale then
        t = t .. tostring(font_scale) .. '%';
      else
        t = t .. translate_now("menu_locale", 'auto_option') .. ' (' .. tostring(font_scale) .. '%)';
      end;
    
      if font_scale < 200 then
        t = t .. ' {#f_more|>>}';
      else
        t = t .. ' >>';
      end;
    
      pn(t .. '^');
    end;
    act = function(s)
      prefs.font_scale = false;
      prefs:store();
    
      set_theme();
      walk(here());    end;
  }: with {
    obj {
      nam = '#f_less';
      act = function(s)
        prefs.font_scale = get_font_scale() - 10;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
    obj {
      nam = '#f_more';
      act = function(s)
        prefs.font_scale = get_font_scale() + 10;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
  };
  obj {
    nam = '#inv_font_scale';
    dsc = function(s)
      if theme.name() ~= '.' then
        return
      end;
      
      local graphic_scale = get_graphic_scale();
      local font_scale = get_inventory_font_scale();
        
      pn(fmt.b(translate_now("menu_locale", 'inventory_scale')) .. ' {[' .. translate_now("menu_locale", 'auto_option') .. ']}');
    
      local t = '';
    
      if font_scale > 50 then
        t = t .. '{#if_less|<<} ';
      else
        t = t .. '<< ';
      end;
    
      if prefs.inventory_scale then
        t = t .. tostring(font_scale) .. '%';
      else
        t = t .. translate_now("menu_locale", 'auto_option') .. ' (' .. tostring(font_scale) .. '%)';
      end;
    
    
      if font_scale < 200 then
        t = t .. ' {#if_more|>>}';
      else
        t = t .. ' >>';
      end;
    
      pn(t .. '^');
    end;
    act = function(s)
      prefs.inventory_scale = false;
    
      prefs:store();
      set_theme(std.call(here(), 'theme'));
      walk(here());
    end;
  }: with {
    obj {
      nam = '#if_less';
      act = function(s)
        prefs.inventory_scale = get_inventory_font_scale() - 10;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
    obj {
      nam = '#if_more';
      act = function(s)
        prefs.inventory_scale = get_inventory_font_scale() + 10;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
  };
  obj {
    nam = '#text_width';
    dsc = function(s)
      if theme.name() ~= '.' then
        return
      end;
      
      pn(fmt.b(translate_now("menu_locale", 'text_width')));
      local t = '';
      if prefs.text_width > 40 then
        t = t .. '{#fw_less|<<} ';
      else
        t = t .. '<< ';
      end;

      t = t .. tostring(prefs.text_width) .. '%';
    
      if prefs.text_width < 100 then
        t = t .. ' {#fw_more|>>}';
      else
        t = t .. ' >>';
      end;
    
      pn(t .. '^');
    end;
    act = function(s)
      if not prefs.text_width then
        prefs.text_width = 100;
      end;
    
      prefs.text_width = prefs.text_width + 20;
    
      if prefs.text_width > 100 then
        prefs.text_width = 40;
      end;
    
      prefs:store();
    
      walk(here());
    end;
  }: with {
    obj {
      nam = '#fw_less';
      act = function(s)
        prefs.text_width = prefs.text_width - 10;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
    obj {
      nam = '#fw_more';
      act = function(s)
        prefs.text_width = prefs.text_width + 10;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
  };
  obj {
    nam = '#text_alignment';
    dsc = function(s)
      if theme.name() ~= '.' then
        return
      end;
      
      pn(fmt.b(translate_now("menu_locale", 'text_alignment')));
      
      local t = '';
    
      if prefs.text_alignment == 1 then
        t = t .. translate_now("menu_locale", 'text_alignment_justify') .. ' | ';
      else
        t = t .. '{#align_just|' .. translate_now("menu_locale", 'text_alignment_justify') .. '} | ';
      end;
      
    
      if prefs.text_alignment == 2 then
        t = t .. translate_now("menu_locale", 'text_alignment_left');
      else
        t = t .. '{#align_left|' .. translate_now("menu_locale", 'text_alignment_left') .. '}';
      end;
      pn(t .. '^');
    end;
  }: with {
    obj {
      nam = '#align_just';
      act = function(s)
        prefs.text_alignment = 1;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
    obj {
      nam = '#align_left';
      act = function(s)
        prefs.text_alignment = 2;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
  };
  obj {
    nam = '#padding';
    dsc = function(s)
      if theme.name() ~= '.' then
        return
      end;
      
      pn(fmt.b(translate_now("menu_locale", 'padding')));
      
      local t = '';
    
      if prefs.text_padding == 1 then
        t = t .. translate_now("menu_locale", 'normal') .. ' | ';
      else
        t = t .. '{#pad_norm|' .. translate_now("menu_locale", 'normal') .. '} | ';
      end;
      
    
      if prefs.text_padding == 2 then
        t = t .. translate_now("menu_locale", 'extended');
      else
        t = t .. '{#pad_large|' .. translate_now("menu_locale", 'extended') .. '}';
      end;
      pn(t .. '^');
    end;
  }: with {
    obj {
      nam = '#pad_norm';
      act = function(s)
        prefs.text_padding = 1;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
    obj {
      nam = '#pad_large';
      act = function(s)
        prefs.text_padding = 2;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
  };
  obj {
    nam = '#interval';
    dsc = function(s)
      if theme.name() ~= '.' then
        return
      end;
      
      pn(fmt.b(translate_now("menu_locale", 'interval')));
      
      local t = '';
    
      if prefs.text_interval == 1 then
        t = t .. translate_now("menu_locale", 'normal') .. ' | ';
      else
        t = t .. '{#int_norm|' .. translate_now("menu_locale", 'normal') .. '} | ';
      end;
      
    
      if prefs.text_interval == 2 then
        t = t .. translate_now("menu_locale", 'extended');
      else
        t = t .. '{#int_large|' .. translate_now("menu_locale", 'extended') .. '}';
      end;
      pn(t .. '^');
    end;
  }: with {
    obj {
      nam = '#int_norm';
      act = function(s)
        prefs.text_interval = 1;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
    obj {
      nam = '#int_large';
      act = function(s)
        prefs.text_interval = 2;
      
        prefs:store();
        set_theme(std.call(here(), 'theme'));
        walk(here());
      end;
    };
  };
}

menu {
  nam = 'settings_menu';
  disp = translate('menu_locale', 'settings');
  inv = function(s)
    timestamp = timestamp - STEP;
    walkin('settings');
  end;
}