/*
 * Copyright (C) 2010 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS CONTRIBUTORS
 * 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.
 */

#pragma once

#include "ConsoleTypes.h"
#include "FloatRect.h"
#include "FontMetrics.h"
#include "GraphicsLayer.h"
#include "GraphicsTypes.h"
#include "MediaPlayer.h"
#include "NativeImagePtr.h"
#include "RefPtrCairo.h"
#include <cairo.h>
#include <wtf/DateMath.h>
#include <wtf/FastAllocBase.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/text/AtomicString.h>
#include <wtf/text/WTFString.h>

#if USE(CURL)
extern "C" {
typedef void CURL;
struct curl_slist;
}
#endif

namespace WebCore
{

class ContentType;
class Cursor;
class Document;
class EspialHTMLObjectElement;
class FloatSize;
class Font;
class FontDescription;
class FontFeatureSettings;
class FontPlatformData;
class FontSelector;
class GCController;
class GLContext;
class Gradient;
class GraphicsContext;
class GraphicsLayerClient;
class HTMLObjectElementPlatformDataBase;
class Image;
class ImageBufferData;
class ImageFrame;
class IntSize;
class JSPropertyDelegate;
class KURL;
class MediaPlayerPrivate;
class PlatformContextCairo;
class PlatformEventLoop;
class ResourceHandle;
class ThreadTimers;
class Widget;
struct FontVariantSettings;

class PlatformDelegate
{
public:
	virtual ~PlatformDelegate() = default;

	virtual NativeImagePtr asNewNativeImage(const ImageFrame&) = 0;

	virtual PassOwnPtr<ImageBufferData> createImageBufferData(const IntSize&, RenderingMode renderingMode, LogGLMemoryError) = 0;
	virtual PassOwnPtr<ImageBufferData> createImageBufferData(const IntSize&, bool /*forceImageSurface*/) = 0;
	virtual PassOwnPtr<ImageBufferData> createImageBufferData(const ImageBufferData& other, const IntSize&, LogGLMemoryError) = 0;
	virtual void setupGraphicsContextProperties(GraphicsContext&) = 0;
	virtual cairo_antialias_t defaultGraphicsAntialias() = 0;

	virtual void imageDecoderBufferMallocFailed(const String& url, int width, int height) = 0;

	virtual bool setImageFrameSize(ImageFrame&, int newWidth, int newHeight, Image* image) = 0;

	virtual bool getSurfaceSize(cairo_surface_t* surface, int& width, int& height) = 0;
	virtual bool getSurfaceFormat(cairo_surface_t* surface, cairo_format_t& format) = 0;

	virtual cairo_surface_t* copySurface(cairo_surface_t* surface) = 0;
	virtual cairo_surface_t* createSurface(cairo_format_t format, float width, float height) = 0;

	virtual bool lockSurface(cairo_surface_t* surface, unsigned char** ret_ptr, int* ret_pitch, bool overwrite) = 0;
	virtual void unlockSurface(cairo_surface_t* surface, bool dirty) = 0;

	virtual bool extractSurfaceData(cairo_surface_t* surface, unsigned char* buffer, int buffer_len) = 0;

	virtual bool platformCanRender(const Gradient&, const FloatSize&) = 0;
	virtual bool shouldCache(const Gradient&, int width, int height) = 0;

#if ENABLE(WEBGL)
	virtual void paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, PlatformContextCairo* context) = 0;
#endif

#if ENABLE(MEDIA_SOURCE)
	virtual bool isSupportedMediaSourceMIMEType(const ContentType& contentType, const String& mimeType, const String& codecs) = 0;
#endif

	virtual void addJob(ResourceHandle*) = 0;
	virtual void cancelJob(ResourceHandle*) = 0;
	virtual void dispatchSynchronousJob(ResourceHandle*) = 0;
	virtual void defersLoadingJob(ResourceHandle* job, bool defers) = 0;

	virtual void freeResourceHandleCustomHeaders(struct curl_slist *list) = 0;

	virtual bool cookiesEnabled(const Document&) = 0;
	virtual String cookies(const KURL&, bool httpOnly) = 0;
	virtual void setCookies(const KURL& url, const String& value) = 0;

	virtual String extraDefaultStyleSheet() = 0;
	virtual String extraDialogStyleSheet() = 0;

	virtual void schedulePurgeInactiveFont() = 0;
	virtual void purgeInactiveFontIfNeeded(int purgePreventCount) = 0;
	virtual bool fontCachePlatformInit() = 0;
	virtual PassRefPtr<Font> fontForPlatformData(const FontPlatformData& platformData) = 0;
	virtual PassRefPtr<Font> fontForFamily(const FontDescription&, const AtomicString& family, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, bool checkingAlternateName) = 0;
	virtual PassRefPtr<Font> systemFallbackForCharacters(const FontDescription&, const Font* originalFontData, bool, const UChar* characters, int length) = 0;
	virtual PassRefPtr<Font> lastResortFallbackFont(const FontDescription& fontDescription) = 0;

	virtual FontMetrics fontPlatformDataMetrics(const FontPlatformData&, const Font* font) = 0;

	virtual FloatRect screenRect(Widget* widget) = 0;
	virtual void setWidgetCursor(Widget& widget, const Cursor& cursor) = 0;

	virtual PassOwnPtr<JSPropertyDelegate> createJSPropertyDelegate(EspialHTMLObjectElement&, const String& url, const String& serviceType) = 0;
	virtual PassOwnPtr<HTMLObjectElementPlatformDataBase> createHTMLObjectElementPlatformData() = 0;

#if USE(ACCELERATED_COMPOSITING)
	virtual PassOwnPtr<WebCore::GraphicsLayer> createGraphicsLayer(WebCore::GraphicsLayerClient* client, WebCore::GraphicsLayer::Type type) = 0;
#endif

#if ENABLE(3D_RENDERING)
	virtual PassOwnPtr<GLContext> createOffscreenContext(bool isDirectGLMode) = 0;
#endif

#if ENABLE(VIDEO)
	virtual void registerMediaEngine(MediaEngineRegistrar) = 0;
#endif

	virtual void addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message) = 0;
	virtual void logMessage(const String&) = 0;
	virtual String defaultLanguage() = 0;
	virtual String platformLanguage() = 0;

	virtual LocalTimeOffset calculateLocalTimeOffset(time_t localTime) = 0;
	virtual double currentTime() = 0;
	virtual double monotonicallyIncreasingTime() = 0;
	virtual int getTimeZoneName(char* buf, int buf_len) = 0;

	virtual void scheduleDispatchFunctionsOnMainThread() = 0;
#if ENABLE(INSPECTOR)
	virtual void eventLoopCycle(PlatformEventLoop&) = 0;
#endif
	virtual void garbageCollectSoon(GCController&) = 0;

	virtual void setSharedTimerFiredFunction(void (*)()) = 0;
	virtual void setSharedTimerFireInterval(double) = 0;
	virtual void stopSharedTimer() = 0;
	virtual void updateSharedTimer(ThreadTimers&) = 0;
	virtual void sharedTimerFired(ThreadTimers&) = 0;

	virtual unsigned jpegMaxMemoryToUse() = 0;

	virtual void setupWebSocket(int socket) { }

protected:
	PlatformDelegate() = default;
};

PlatformDelegate& platformDelegate();
void setPlatformDelegate(PlatformDelegate&);

}
