001// --------------------------------------------------------------------------------
002// Copyright 2002-2026 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.model.control.core.server.graphql;
018
019import com.echothree.model.control.core.server.control.AppearanceControl;
020import com.echothree.model.control.graphql.server.graphql.BaseEntityInstanceObject;
021import com.echothree.model.control.graphql.server.graphql.count.CountedObjects;
022import com.echothree.model.control.graphql.server.graphql.count.CountingDataConnectionFetcher;
023import com.echothree.model.control.graphql.server.graphql.count.CountingPaginatedData;
024import com.echothree.model.control.graphql.server.util.BaseGraphQl;
025import com.echothree.model.control.graphql.server.util.count.ObjectLimiter;
026import com.echothree.model.control.user.server.control.UserControl;
027import com.echothree.model.data.core.common.AppearanceTextDecorationConstants;
028import com.echothree.model.data.core.common.AppearanceTextTransformationConstants;
029import com.echothree.model.data.core.server.entity.Appearance;
030import com.echothree.model.data.core.server.entity.AppearanceDetail;
031import com.echothree.util.server.persistence.Session;
032import graphql.annotations.annotationTypes.GraphQLDescription;
033import graphql.annotations.annotationTypes.GraphQLField;
034import graphql.annotations.annotationTypes.GraphQLName;
035import graphql.annotations.annotationTypes.GraphQLNonNull;
036import graphql.annotations.connection.GraphQLConnection;
037import graphql.schema.DataFetchingEnvironment;
038import java.util.ArrayList;
039import java.util.stream.Collectors;
040
041@GraphQLDescription("appearance object")
042@GraphQLName("Appearance")
043public class AppearanceObject
044        extends BaseEntityInstanceObject {
045    
046    private final Appearance appearance; // Always Present
047    
048    public AppearanceObject(Appearance appearance) {
049        super(appearance.getPrimaryKey());
050        
051        this.appearance = appearance;
052    }
053
054    private AppearanceDetail appearanceDetail; // Optional, use getAppearanceDetail()
055    
056    private AppearanceDetail getAppearanceDetail() {
057        if(appearanceDetail == null) {
058            appearanceDetail = appearance.getLastDetail();
059        }
060        
061        return appearanceDetail;
062    }
063    
064    @GraphQLField
065    @GraphQLDescription("appearance name")
066    @GraphQLNonNull
067    public String getAppearanceName() {
068        return getAppearanceDetail().getAppearanceName();
069    }
070    
071    @GraphQLField
072    @GraphQLDescription("text color")
073    public ColorObject getTextColor() {
074        var textColor = getAppearanceDetail().getTextColor();
075        
076        return textColor == null ? null : new ColorObject(textColor);
077    }
078    
079    @GraphQLField
080    @GraphQLDescription("background color")
081    public ColorObject getBackgroundColor() {
082        var backgroundColor = getAppearanceDetail().getBackgroundColor();
083        
084        return backgroundColor == null ? null : new ColorObject(backgroundColor);
085    }
086    
087    @GraphQLField
088    @GraphQLDescription("font style")
089    public FontStyleObject getFontStyle() {
090        var fontStyle = getAppearanceDetail().getFontStyle();
091        
092        return fontStyle == null ? null : new FontStyleObject(fontStyle);
093    }
094    
095    @GraphQLField
096    @GraphQLDescription("font weight")
097    public FontWeightObject getFontWeight() {
098        var fontWeight = getAppearanceDetail().getFontWeight();
099        
100        return fontWeight == null ? null : new FontWeightObject(fontWeight);
101    }
102    
103    @GraphQLField
104    @GraphQLDescription("is default")
105    @GraphQLNonNull
106    public boolean getIsDefault() {
107        return getAppearanceDetail().getIsDefault();
108    }
109    
110    @GraphQLField
111    @GraphQLDescription("sort order")
112    @GraphQLNonNull
113    public int getSortOrder() {
114        return getAppearanceDetail().getSortOrder();
115    }
116    
117    @GraphQLField
118    @GraphQLDescription("description")
119    @GraphQLNonNull
120    public String getDescription(final DataFetchingEnvironment env) {
121        var appearanceControl = Session.getModelController(AppearanceControl.class);
122        var userControl = Session.getModelController(UserControl.class);
123
124        return appearanceControl.getBestAppearanceDescription(appearance, userControl.getPreferredLanguageFromUserVisit(BaseGraphQl.getUserVisit(env)));
125    }
126
127    @GraphQLField
128    @GraphQLDescription("appearance text decorations")
129    @GraphQLNonNull
130    @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class)
131    public CountingPaginatedData<AppearanceTextDecorationObject> getAppearanceTextDecorations(final DataFetchingEnvironment env) {
132        CountingPaginatedData<AppearanceTextDecorationObject> objects;
133        var appearanceControl = Session.getModelController(AppearanceControl.class);
134        var totalCount = appearanceControl.countAppearanceTextDecorationsByAppearance(appearance);
135
136        try(var objectLimiter = new ObjectLimiter(env, AppearanceTextDecorationConstants.COMPONENT_VENDOR_NAME, AppearanceTextDecorationConstants.ENTITY_TYPE_NAME, totalCount)) {
137            var entities = appearanceControl.getAppearanceTextDecorationsByAppearance(appearance);
138            var items = entities.stream()
139                    .map(AppearanceTextDecorationObject::new)
140                    .collect(Collectors.toCollection(() -> new ArrayList<>(entities.size())));
141
142            objects = new CountedObjects<>(objectLimiter, items);
143        }
144
145        return objects;
146    }
147
148    @GraphQLField
149    @GraphQLDescription("appearance text transformations")
150    @GraphQLNonNull
151    @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class)
152    public CountingPaginatedData<AppearanceTextTransformationObject> getAppearanceTextTransformations(final DataFetchingEnvironment env) {
153        CountingPaginatedData<AppearanceTextTransformationObject> objects;
154        var appearanceControl = Session.getModelController(AppearanceControl.class);
155        var totalCount = appearanceControl.countAppearanceTextTransformationsByAppearance(appearance);
156
157        try(var objectLimiter = new ObjectLimiter(env, AppearanceTextTransformationConstants.COMPONENT_VENDOR_NAME, AppearanceTextTransformationConstants.ENTITY_TYPE_NAME, totalCount)) {
158            var entities = appearanceControl.getAppearanceTextTransformationsByAppearance(appearance);
159            var items = entities.stream()
160                    .map(AppearanceTextTransformationObject::new)
161                    .collect(Collectors.toCollection(() -> new ArrayList<>(entities.size())));
162
163            objects = new CountedObjects<>(objectLimiter, items);
164        }
165
166        return objects;
167    }
168
169}