// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sommelier.h"

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <wayland-client.h>

#include "aura-shell-client-protocol.h"

#define MAX_OUTPUT_SCALE 2

#define INCH_IN_MM 25.4

double sl_output_aura_scale_factor_to_double(int scale_factor) {
  // Aura scale factor is an enum that for all currently know values
  // is a scale value multipled by 1000. For example, enum value for
  // 1.25 scale factor is 1250.
  return scale_factor / 1000.0;
}

void sl_output_get_host_output_state(struct sl_host_output* host,
                                     int* scale,
                                     int* physical_width,
                                     int* physical_height,
                                     int* width,
                                     int* height) {
  double preferred_scale =
      sl_output_aura_scale_factor_to_double(host->preferred_scale);
  double current_scale =
      sl_output_aura_scale_factor_to_double(host->current_scale);
  double ideal_scale_factor = 1.0;
  double scale_factor = host->scale_factor;

  // Use the scale factor we received from aura shell protocol when available.
  if (host->ctx->aura_shell) {
    double device_scale_factor =
        sl_output_aura_scale_factor_to_double(host->device_scale_factor);

    ideal_scale_factor = device_scale_factor * preferred_scale;
    scale_factor = device_scale_factor * current_scale;
  }

  // Always use scale=1 and adjust geometry and mode based on ideal
  // scale factor for Xwayland client. For other clients, pick an optimal
  // scale and adjust geometry and mode based on it.
  if (host->ctx->xwayland) {
    if (scale)
      *scale = 1;
    *physical_width = host->physical_width * ideal_scale_factor / scale_factor;
    *physical_height =
        host->physical_height * ideal_scale_factor / scale_factor;
    *width = host->width * host->ctx->scale / scale_factor;
    *height = host->height * host->ctx->scale / scale_factor;
  } else {
    int s = MIN(ceil(scale_factor / host->ctx->scale), MAX_OUTPUT_SCALE);

    if (scale)
      *scale = s;
    *physical_width = host->physical_width;
    *physical_height = host->physical_height;
    *width = host->width * host->ctx->scale * s / scale_factor;
    *height = host->height * host->ctx->scale * s / scale_factor;
  }

  if (host->ctx->dpi.size) {
    int dpi = (*width * INCH_IN_MM) / *physical_width;
    int adjusted_dpi = *((int*)host->ctx->dpi.data);
    double mmpd;
    int* p;

    wl_array_for_each(p, &host->ctx->dpi) {
      if (*p > dpi)
        break;

      adjusted_dpi = *p;
    }

    mmpd = INCH_IN_MM / adjusted_dpi;
    *physical_width = *width * mmpd + 0.5;
    *physical_height = *height * mmpd + 0.5;
  }
}

void sl_output_send_host_output_state(struct sl_host_output* host) {
  int scale;
  int physical_width;
  int physical_height;
  int width;
  int height;

  sl_output_get_host_output_state(host, &scale, &physical_width,
                                  &physical_height, &width, &height);

  // Use density of internal display for all Xwayland outputs. X11 clients
  // typically lack support for dynamically changing density so it's
  // preferred to always use the density of the internal display.
  if (host->ctx->xwayland) {
    struct sl_host_output* output;

    wl_list_for_each(output, &host->ctx->host_outputs, link) {
      if (output->internal) {
        int internal_width;
        int internal_height;

        sl_output_get_host_output_state(output, NULL, &physical_width,
                                        &physical_height, &internal_width,
                                        &internal_height);

        physical_width = (physical_width * width) / internal_width;
        physical_height = (physical_height * height) / internal_height;
        break;
      }
    }
  }

  // X/Y are best left at origin as managed X windows are kept centered on
  // the root window. The result is that all outputs are overlapping and
  // pointer events can always be dispatched to the visible region of the
  // window.
  wl_output_send_geometry(host->resource, 0, 0, physical_width, physical_height,
                          host->subpixel, host->make, host->model,
                          host->transform);
  wl_output_send_mode(host->resource, host->flags | WL_OUTPUT_MODE_CURRENT,
                      width, height, host->refresh);
  if (wl_resource_get_version(host->resource) >= WL_OUTPUT_SCALE_SINCE_VERSION)
    wl_output_send_scale(host->resource, scale);
  if (wl_resource_get_version(host->resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
    wl_output_send_done(host->resource);
}

static void sl_output_geometry(void* data,
                               struct wl_output* output,
                               int x,
                               int y,
                               int physical_width,
                               int physical_height,
                               int subpixel,
                               const char* make,
                               const char* model,
                               int transform) {
  struct sl_host_output* host = wl_output_get_user_data(output);

  host->x = x;
  host->y = y;
  host->physical_width = physical_width;
  host->physical_height = physical_height;
  host->subpixel = subpixel;
  free(host->model);
  host->model = strdup(model);
  free(host->make);
  host->make = strdup(make);
  host->transform = transform;
}

static void sl_output_mode(void* data,
                           struct wl_output* output,
                           uint32_t flags,
                           int width,
                           int height,
                           int refresh) {
  struct sl_host_output* host = wl_output_get_user_data(output);

  host->flags = flags;
  host->width = width;
  host->height = height;
  host->refresh = refresh;
}

static void sl_output_done(void* data, struct wl_output* output) {
  struct sl_host_output* host = wl_output_get_user_data(output);

  // Early out if scale is expected but not yet know.
  if (host->expecting_scale)
    return;

  sl_output_send_host_output_state(host);

  // Expect scale if aura output exists.
  if (host->aura_output)
    host->expecting_scale = 1;
}

static void sl_output_scale(void* data,
                            struct wl_output* output,
                            int32_t scale_factor) {
  struct sl_host_output* host = wl_output_get_user_data(output);

  host->scale_factor = scale_factor;
}

static const struct wl_output_listener sl_output_listener = {
    sl_output_geometry, sl_output_mode, sl_output_done, sl_output_scale};

static void sl_aura_output_scale(void* data,
                                 struct zaura_output* output,
                                 uint32_t flags,
                                 uint32_t scale) {
  struct sl_host_output* host = zaura_output_get_user_data(output);

  switch (scale) {
    case ZAURA_OUTPUT_SCALE_FACTOR_0400:
    case ZAURA_OUTPUT_SCALE_FACTOR_0500:
    case ZAURA_OUTPUT_SCALE_FACTOR_0550:
    case ZAURA_OUTPUT_SCALE_FACTOR_0600:
    case ZAURA_OUTPUT_SCALE_FACTOR_0625:
    case ZAURA_OUTPUT_SCALE_FACTOR_0650:
    case ZAURA_OUTPUT_SCALE_FACTOR_0700:
    case ZAURA_OUTPUT_SCALE_FACTOR_0750:
    case ZAURA_OUTPUT_SCALE_FACTOR_0800:
    case ZAURA_OUTPUT_SCALE_FACTOR_0850:
    case ZAURA_OUTPUT_SCALE_FACTOR_0900:
    case ZAURA_OUTPUT_SCALE_FACTOR_0950:
    case ZAURA_OUTPUT_SCALE_FACTOR_1000:
    case ZAURA_OUTPUT_SCALE_FACTOR_1050:
    case ZAURA_OUTPUT_SCALE_FACTOR_1100:
    case ZAURA_OUTPUT_SCALE_FACTOR_1150:
    case ZAURA_OUTPUT_SCALE_FACTOR_1125:
    case ZAURA_OUTPUT_SCALE_FACTOR_1200:
    case ZAURA_OUTPUT_SCALE_FACTOR_1250:
    case ZAURA_OUTPUT_SCALE_FACTOR_1300:
    case ZAURA_OUTPUT_SCALE_FACTOR_1400:
    case ZAURA_OUTPUT_SCALE_FACTOR_1450:
    case ZAURA_OUTPUT_SCALE_FACTOR_1500:
    case ZAURA_OUTPUT_SCALE_FACTOR_1600:
    case ZAURA_OUTPUT_SCALE_FACTOR_1750:
    case ZAURA_OUTPUT_SCALE_FACTOR_1800:
    case ZAURA_OUTPUT_SCALE_FACTOR_2000:
    case ZAURA_OUTPUT_SCALE_FACTOR_2200:
    case ZAURA_OUTPUT_SCALE_FACTOR_2250:
    case ZAURA_OUTPUT_SCALE_FACTOR_2500:
    case ZAURA_OUTPUT_SCALE_FACTOR_2750:
    case ZAURA_OUTPUT_SCALE_FACTOR_3000:
    case ZAURA_OUTPUT_SCALE_FACTOR_3500:
    case ZAURA_OUTPUT_SCALE_FACTOR_4000:
    case ZAURA_OUTPUT_SCALE_FACTOR_4500:
    case ZAURA_OUTPUT_SCALE_FACTOR_5000:
      break;
    default:
      fprintf(stderr, "warning: unknown scale factor: %d\n", scale);
      break;
  }

  if (flags & ZAURA_OUTPUT_SCALE_PROPERTY_CURRENT)
    host->current_scale = scale;
  if (flags & ZAURA_OUTPUT_SCALE_PROPERTY_PREFERRED)
    host->preferred_scale = scale;

  host->expecting_scale = 0;
}

static void sl_aura_output_connection(void* data,
                                      struct zaura_output* output,
                                      uint32_t connection) {
  struct sl_host_output* host = zaura_output_get_user_data(output);

  host->internal = connection == ZAURA_OUTPUT_CONNECTION_TYPE_INTERNAL;
}

static void sl_aura_output_device_scale_factor(void* data,
                                               struct zaura_output* output,
                                               uint32_t device_scale_factor) {
  struct sl_host_output* host = zaura_output_get_user_data(output);

  host->device_scale_factor = device_scale_factor;
}

static const struct zaura_output_listener sl_aura_output_listener = {
    sl_aura_output_scale, sl_aura_output_connection,
    sl_aura_output_device_scale_factor};

static void sl_destroy_host_output(struct wl_resource* resource) {
  struct sl_host_output* host = wl_resource_get_user_data(resource);

  if (host->aura_output)
    zaura_output_destroy(host->aura_output);
  if (wl_output_get_version(host->proxy) >= WL_OUTPUT_RELEASE_SINCE_VERSION) {
    wl_output_release(host->proxy);
  } else {
    wl_output_destroy(host->proxy);
  }
  wl_resource_set_user_data(resource, NULL);
  wl_list_remove(&host->link);
  free(host->make);
  free(host->model);
  free(host);
}

static void sl_bind_host_output(struct wl_client* client,
                                void* data,
                                uint32_t version,
                                uint32_t id) {
  struct sl_output* output = (struct sl_output*)data;
  struct sl_context* ctx = output->ctx;
  struct sl_host_output* host;

  host = malloc(sizeof(*host));
  assert(host);
  host->ctx = ctx;
  host->resource = wl_resource_create(client, &wl_output_interface,
                                      MIN(version, output->version), id);
  wl_resource_set_implementation(host->resource, NULL, host,
                                 sl_destroy_host_output);
  host->proxy = wl_registry_bind(wl_display_get_registry(ctx->display),
                                 output->id, &wl_output_interface,
                                 wl_resource_get_version(host->resource));
  wl_output_set_user_data(host->proxy, host);
  wl_output_add_listener(host->proxy, &sl_output_listener, host);
  host->aura_output = NULL;
  // We assume that first output is internal by default.
  host->internal = wl_list_empty(&ctx->host_outputs);
  host->x = 0;
  host->y = 0;
  host->physical_width = 0;
  host->physical_height = 0;
  host->subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
  host->make = strdup("unknown");
  host->model = strdup("unknown");
  host->transform = WL_OUTPUT_TRANSFORM_NORMAL;
  host->flags = 0;
  host->width = 1024;
  host->height = 768;
  host->refresh = 60000;
  host->scale_factor = 1;
  host->current_scale = 1000;
  host->preferred_scale = 1000;
  host->device_scale_factor = 1000;
  host->expecting_scale = 0;
  wl_list_insert(ctx->host_outputs.prev, &host->link);
  if (ctx->aura_shell) {
    host->expecting_scale = 1;
    host->internal = 0;
    host->aura_output =
        zaura_shell_get_aura_output(ctx->aura_shell->internal, host->proxy);
    zaura_output_set_user_data(host->aura_output, host);
    zaura_output_add_listener(host->aura_output, &sl_aura_output_listener,
                              host);
  }
}

struct sl_global* sl_output_global_create(struct sl_output* output) {
  return sl_global_create(output->ctx, &wl_output_interface, output->version,
                          output, sl_bind_host_output);
}
