//Copyright 2015 Erik De Rijcke
//
//Licensed under the Apache License,Version2.0(the"License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing,software
//distributed under the License is distributed on an"AS IS"BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package org.westmalle.wayland.protocol;


import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;
import com.google.common.collect.Sets;
import org.freedesktop.wayland.server.*;
import org.freedesktop.wayland.shared.WlSeatCapability;

import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import java.util.Optional;
import java.util.Set;

@AutoFactory(className = "WlSeatFactory")
public class WlSeat extends Global<WlSeatResource> implements WlSeatRequestsV4, ProtocolObject<WlSeatResource> {

    private final Set<WlSeatResource> resources = Sets.newHashSet();

    private Optional<WlPointer>  optionalWlPointer  = Optional.empty();
    private Optional<WlKeyboard> optionalWlKeyboard = Optional.empty();
    private Optional<WlTouch>    optionalWlTouch    = Optional.empty();

    WlSeat(@Provided final Display display) {
        super(display,
              WlSeatResource.class,
              VERSION);
    }

    @Override
    public WlSeatResource onBindClient(final Client client,
                                       final int version,
                                       final int id) {
        //FIXME check if we support given version.
        return add(client,
                   version,
                   id);
    }

    @Override
    public void getPointer(final WlSeatResource resource,
                           final int id) {
        this.optionalWlPointer.ifPresent(wlPointer ->
                                                 wlPointer.add(resource.getClient(),
                                                               resource.getVersion(),
                                                               id));
    }

    @Override
    public void getKeyboard(final WlSeatResource resource,
                            final int id) {
        this.optionalWlKeyboard.ifPresent(wlKeyboard ->
                                                  wlKeyboard.add(resource.getClient(),
                                                                 resource.getVersion(),
                                                                 id));
    }

    @Override
    public void getTouch(final WlSeatResource resource,
                         final int id) {
        this.optionalWlTouch.ifPresent(wlTouch ->
                                               wlTouch.add(resource.getClient(),
                                                           resource.getVersion(),
                                                           id));
    }

    @Nonnull
    @Override
    public Set<WlSeatResource> getResources() {
        return this.resources;
    }

    @Nonnull
    @Override
    public WlSeatResource create(@Nonnull final Client client,
                                 @Nonnegative final int version,
                                 final int id) {
        final WlSeatResource resource = new WlSeatResource(client,
                                                           version,
                                                           id,
                                                           this);
        emiteCapabilities(resource);
        return resource;
    }

    private void emiteCapabilities(final WlSeatResource wlSeatResource) {
        int capabilities = 0;
        if (this.optionalWlPointer.isPresent()) {
            capabilities |= WlSeatCapability.POINTER.getValue();
        }
        if (this.optionalWlKeyboard.isPresent()) {
            capabilities |= WlSeatCapability.KEYBOARD.getValue();
        }
        if (this.optionalWlTouch.isPresent()) {
            capabilities |= WlSeatCapability.TOUCH.getValue();
        }
        wlSeatResource.capabilities(capabilities);
    }

    public Optional<WlKeyboard> getOptionalWlKeyboard() {
        return this.optionalWlKeyboard;
    }

    public void setWlKeyboard(final WlKeyboard wlKeyboard) {

    }

    public void removeWlKeyboard() {

    }

    public Optional<WlPointer> getOptionalWlPointer() {
        return this.optionalWlPointer;
    }

    public void setWlPointer(@Nonnull final WlPointer newWlPointer) {
        //destroy the previous pointer
        this.optionalWlPointer.ifPresent(wlPointer -> wlPointer.getResources()
                                                               .forEach(Resource::destroy));
        this.optionalWlPointer = Optional.of(newWlPointer);
        getResources().forEach(this::emiteCapabilities);
    }

    public void removeWlPointer() {
        this.optionalWlPointer.ifPresent(wlPointer -> wlPointer.getResources()
                                                               .forEach(org.freedesktop.wayland.server.WlPointerResource::destroy));
        this.optionalWlPointer = Optional.empty();
        getResources().forEach(this::emiteCapabilities);
    }


    public Optional<WlTouch> getOptionalWlTouch() {
        return this.optionalWlTouch;
    }

    public void setWlTouch() {

    }

    public void removeWlTouch() {

    }
}

@@ -4424,17 +4424,20 @@
 eyboard 
-w
+newW
 lKeyboar
@@ -4445,815 +4445,618 @@
 ) %7B%0A
-%0A    %7D%0A%0A    public void removeWlKeyboard() %7B%0A%0A    %7D%0A%0A    public Optional%3CWlPointer%3E getOptionalWlPointer() %7B%0A        return this.optionalWlPointer;%0A    %7D%0A%0A    public void setWlPointer(@Nonnull final WlPointer newWlPointer) %7B%0A        //destroy the previous pointer%0A        this.optionalWlPointer.ifPresent(wlPointer -%3E wlPointer.getResources()%0A                                                               .forEach(Resource::destroy));%0A        this.optionalWlPointer = Optional.of(newWlPointer);%0A        getResources().forEach(this::emiteCapabilities);%0A    %7D%0A%0A    public void removeWlPointer() %7B%0A        this.optionalWlPointer.ifPresent(wlPointer -%3E wlPointer.getResources()%0A                                                               .forEach(org.freedesktop.wayland.server.WlPointerResource::destroy));
+        this.optionalWlKeyboard = Optional.of(newWlKeyboard);%0A        getResources().forEach(this::emiteCapabilities);%0A    %7D%0A%0A    public void removeWlKeyboard() %7B%0A        this.optionalWlKeyboard = Optional.empty();%0A        getResources().forEach(this::emiteCapabilities);%0A    %7D%0A%0A    public Optional%3CWlPointer%3E getOptionalWlPointer() %7B%0A        return this.optionalWlPointer;%0A    %7D%0A%0A    public void setWlPointer(@Nonnull final WlPointer newWlPointer) %7B%0A        this.optionalWlPointer = Optional.of(newWlPointer);%0A        getResources().forEach(this::emiteCapabilities);%0A    %7D%0A%0A    public void removeWlPointer() %7B
 %0A   
@@ -5167,17 +5167,16 @@
 %0A    %7D%0A%0A
-%0A
     publ
@@ -5294,59 +5294,294 @@
 uch(
-) %7B%0A%0A    %7D%0A%0A    public void removeWlTouch() %7B%0A
+final WlTouch wlTouch) %7B%0A        this.optionalWlTouch = Optional.of(wlTouch);%0A        getResources().forEach(this::emiteCapabilities);%0A    %7D%0A%0A    public void removeWlTouch() %7B%0A        this.optionalWlTouch = Optional.empty();%0A        getResources().forEach(this::emiteCapabilities);
 %0A    %7D%0A%7D
 %0A
@@ -5579,9 +5579,8 @@
 %0A    %7D%0A%7D
-%0A

implement wltouch & wlkeyboard registration