1168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak/*
2168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * Copyright 2016, The Android Open Source Project
3168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak *
4168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * Licensed under the Apache License, Version 2.0 (the "License");
5168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * you may not use this file except in compliance with the License.
6168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * You may obtain a copy of the License at
7168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak *
8168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak *     http://www.apache.org/licenses/LICENSE-2.0
9168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak *
10168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * Unless required by applicable law or agreed to in writing, software
11168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * distributed under the License is distributed on an "AS IS" BASIS,
12168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * See the License for the specific language governing permissions and
14168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * limitations under the License.
15168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak */
16168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
17168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzakpackage com.android.managedprovisioning.common;
18168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
19168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzakimport android.app.Activity;
20168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzakimport android.app.AlertDialog;
21168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzakimport android.app.Dialog;
22168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzakimport android.app.DialogFragment;
23168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzakimport android.content.DialogInterface;
24168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzakimport android.os.Bundle;
25168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
26168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak/**
27168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * Utility class wrapping a {@link AlertDialog} in a {@link DialogFragment}
28168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * <p> In order to properly handle Dialog lifecycle we follow the practice of wrapping of them
29168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * in a Dialog Fragment.
30168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * <p> If buttons are to be used (enabled by setting a button message), the creator {@link Activity}
31168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak * must implement {@link SimpleDialogListener}.
32168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak */
33168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzakpublic class SimpleDialog extends DialogFragment {
34168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    private static final String TITLE = "title";
35168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    private static final String MESSAGE = "message";
36168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    private static final String NEGATIVE_BUTTON_MESSAGE = "negativeButtonMessage";
37168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    private static final String POSITIVE_BUTTON_MESSAGE = "positiveButtonMessage";
38168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
39168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    /**
40168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     * Use the {@link Builder} instead. Keeping the constructor public only because
41168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     * a {@link DialogFragment} must have an empty constructor that is public.
42168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     */
43168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    public SimpleDialog() {
44168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    }
45168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
46168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    @Override
47083bad2a144edf9e8a7acc4d6c09df413749afaeJakub Gielzak    public AlertDialog onCreateDialog(Bundle savedInstanceState) {
48168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        final SimpleDialogListener dialogListener = (SimpleDialogListener) getActivity();
49168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
50168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
51168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
52168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        Bundle args = getArguments();
53168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        if (args.containsKey(TITLE)) {
54168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            builder.setTitle(args.getInt(TITLE));
55168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        }
56168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
57168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        if (args.containsKey(MESSAGE)) {
58168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            builder.setMessage(args.getInt(MESSAGE));
59168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        }
60168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
61168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        if (args.containsKey(NEGATIVE_BUTTON_MESSAGE)) {
62168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            builder.setNegativeButton(args.getInt(NEGATIVE_BUTTON_MESSAGE),
63168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                    new DialogInterface.OnClickListener() {
64168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                @Override
65168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                public void onClick(DialogInterface dialog, int which) {
66168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                    dialogListener.onNegativeButtonClick(SimpleDialog.this);
67168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                }
68168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            });
69168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        }
70168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
71168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        if (args.containsKey(POSITIVE_BUTTON_MESSAGE)) {
72168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            builder.setPositiveButton(args.getInt(POSITIVE_BUTTON_MESSAGE),
73168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                    new DialogInterface.OnClickListener() {
74168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                @Override
75168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                public void onClick(DialogInterface dialog, int which) {
76168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                    dialogListener.onPositiveButtonClick(SimpleDialog.this);
77168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                }
78168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            });
79168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        }
80168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
81168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        return builder.create();
82168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    }
83168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
84168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    /**
85168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     * Throws an exception informing of a lack of a handler for a dialog button click
86168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     * <p> Useful when implementing {@link SimpleDialogListener}
87168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     */
88168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    public static void throwButtonClickHandlerNotImplemented(DialogFragment dialog) {
89168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        throw new IllegalArgumentException("Button click handler not implemented for dialog: "
90168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                + dialog.getTag());
91168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    }
92168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
93168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    public static class Builder implements DialogBuilder {
94168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        private Integer mTitle;
95168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        private Integer mMessage;
96168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        private Integer mNegativeButtonMessage;
97168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        private Integer mPositiveButtonMessage;
98168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        private Boolean mCancelable;
99168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
100168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        /**
101168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * Sets the title
102168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * @param title Title resource id.
103168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         */
104d4c471e22aae4572795c67096e41367c23ef4164Victor Chang        public Builder setTitle(Integer title) {
105168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            mTitle = title;
106168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            return this;
107168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        }
108168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
109168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        /**
110168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * Sets the message
111168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * @param message Message resource id.
112168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         */
113168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        public Builder setMessage(int message) {
114168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            mMessage = message;
115168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            return this;
116168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        }
117168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
118168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        /**
119168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * Sets a message for the button.
120168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * <p> Makes the button appear (without setting a button message, a button is not displayed)
121168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * <p> Callback must be handled by a creator {@link Activity},
122168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * which must implement {@link SimpleDialogListener}.
123168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * @param negativeButtonMessage Message resource id.
124168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         */
125168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        public Builder setNegativeButtonMessage(int negativeButtonMessage) {
126168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            mNegativeButtonMessage = negativeButtonMessage;
127168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            return this;
128168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        }
129168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
130168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        /**
131168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * Sets a message for the button.
132168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * <p> Makes the button appear (without setting a button message, a button is not displayed)
133168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * <p> Callback must be handled by a creator {@link Activity},
134168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * which must implement {@link SimpleDialogListener}.
135168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * @param positiveButtonMessage Message resource id.
136168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         */
137168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        public Builder setPositiveButtonMessage(int positiveButtonMessage) {
138168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            mPositiveButtonMessage = positiveButtonMessage;
139168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            return this;
140168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        }
141168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
142168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        /**
143168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * Sets whether the dialog is cancelable or not.  Default is true.
144168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         */
145168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        public Builder setCancelable(boolean cancelable) {
146168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            mCancelable = cancelable;
147168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            return this;
148168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        }
149168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
150168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        /**
151168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * Creates an {@link SimpleDialog} with the arguments supplied to this builder.
152168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         */
153168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        @Override
154168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        public SimpleDialog build() {
155168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            SimpleDialog instance = new SimpleDialog();
156168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            Bundle args = new Bundle();
157168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
158168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            if (mTitle != null) {
159168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                args.putInt(TITLE, mTitle);
160168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            }
161168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
162168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            if (mMessage != null) {
163168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                args.putInt(MESSAGE, mMessage);
164168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            }
165168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
166168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            if (mNegativeButtonMessage != null) {
167168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                args.putInt(NEGATIVE_BUTTON_MESSAGE, mNegativeButtonMessage);
168168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            }
169168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
170168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            if (mPositiveButtonMessage != null) {
171168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                args.putInt(POSITIVE_BUTTON_MESSAGE, mPositiveButtonMessage);
172168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            }
173168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
174168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            if (mCancelable != null) {
175168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak                instance.setCancelable(mCancelable);
176168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            }
177168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
178168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            instance.setArguments(args);
179168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak            return instance;
180168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        }
181168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    }
182168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
183168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    /**
184168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     * Interface for handling callbacks from {@link SimpleDialog} buttons.
185168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     *
186168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     * <p>If multiple dialogs are used in a context of a single {@link Activity},
187168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     * a consumer of the interface can differentiate between dialogs using
188168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     * e.g. a {@link DialogFragment#getTag()}, or {@link DialogFragment#getArguments()}.
189168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak     */
190168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    public interface SimpleDialogListener {
191168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        /**
192168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * Called when a user clicks on the positive dialog button.
193168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * <p> To be implemented by a host {@link Activity} object.
194168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * @param dialog {@link DialogFragment} where the click happened.
195168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         */
196168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        void onPositiveButtonClick(DialogFragment dialog);
197168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak
198168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        /**
199168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * Called when a user clicks on the negative dialog button.
200168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * <p> To be implemented by a host {@link Activity} object.
201168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         * @param dialog {@link DialogFragment} where the click happened.
202168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak         */
203168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak        void onNegativeButtonClick(DialogFragment dialog);
204168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak    }
205168242f93d251757ba6d25ab9b82d3318d5c4bc6Jakub Gielzak}