#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#
#
# Copyright (c) 2008-2015 University of Dundee.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Author: Aleksandra Tarkowska <A(dot)Tarkowska(at)dundee(dot)ac(dot)uk>, 2008.
#
# Version: 1.0
#

import datetime
import time
import logging

from django.conf import settings
from django import forms
from django.forms.formsets import formset_factory
from django.core.urlresolvers import reverse

from omeroweb.custom_forms import NonASCIIForm
from .custom_forms import MetadataModelChoiceField
from .custom_forms import AnnotationModelMultipleChoiceField
from .custom_forms import ObjectModelMultipleChoiceField
from omeroweb.webadmin.custom_forms import ExperimenterModelMultipleChoiceField
from omeroweb.webadmin.custom_forms import GroupModelChoiceField
from omeroweb.webclient.webclient_utils import formatPercentFraction

logger = logging.getLogger(__name__)


##################################################################
# Static values

# TODO: change to reverse
help_button = "%swebgateway/img/help16.png" % settings.STATIC_URL

help_enable = (
    '<span class="tooltip" title="Enable/Disable: This option'
    ' allows the owner to keep the access control of the share.">'
    '<img src="%s" /></span>'
) % help_button

help_expire = (
    '<span class="tooltip" title="Expiry date: This date defines'
    " when the share will stop being available. Date format:"
    ' YYYY-MM-DD."><img src="%s" /></span>'
) % help_button


#################################################################
# Non-model Form


class GlobalSearchForm(NonASCIIForm):

    search_query = forms.CharField(widget=forms.TextInput(attrs={"size": 25}))


class ShareForm(NonASCIIForm):
    def __init__(self, *args, **kwargs):
        super(ShareForm, self).__init__(*args, **kwargs)

        try:
            if kwargs["initial"]["shareMembers"]:
                pass
            self.fields["members"] = ExperimenterModelMultipleChoiceField(
                queryset=kwargs["initial"]["experimenters"],
                initial=kwargs["initial"]["shareMembers"],
                widget=forms.SelectMultiple(attrs={"size": 28}),
            )
        except Exception:
            self.fields["members"] = ExperimenterModelMultipleChoiceField(
                queryset=kwargs["initial"]["experimenters"],
                widget=forms.SelectMultiple(attrs={"size": 28}),
            )
        self.fields.keyOrder = [
            "message",
            "expiration",
            "enable",
            "members",
        ]  # , 'guests']

    message = forms.CharField(widget=forms.Textarea(attrs={"rows": 5, "cols": 50}))
    expiration = forms.CharField(
        max_length=100,
        widget=forms.TextInput(attrs={"size": 10}),
        label="Expiry date",
        help_text=help_expire,
        required=False,
    )
    enable = forms.BooleanField(required=False, help_text=help_enable)
    # guests = MultiEmailField(required=False,
    # widget=forms.TextInput(attrs={'size':75}))

    def clean_expiration(self):
        if (
            self.cleaned_data["expiration"] is not None
            and len(self.cleaned_data["expiration"]) < 1
        ):
            return None
        if self.cleaned_data["expiration"] is not None:
            d = str(self.cleaned_data["expiration"]).rsplit("-")
            try:
                date = datetime.datetime.strptime(
                    ("%s-%s-%s" % (d[0], d[1], d[2])), "%Y-%m-%d"
                )
            except Exception:
                raise forms.ValidationError("Date is in the wrong format. YY-MM-DD")
            if time.mktime(date.timetuple()) <= time.time():
                raise forms.ValidationError("Expiry date must be in the future.")
        return self.cleaned_data["expiration"]


class ContainerForm(NonASCIIForm):

    name = forms.CharField(max_length=250, widget=forms.TextInput(attrs={"size": 45}))
    description = forms.CharField(
        widget=forms.Textarea(attrs={"rows": 2, "cols": 49}), required=False
    )
    owner = forms.CharField(widget=forms.HiddenInput, required=False)


class ContainerNameForm(NonASCIIForm):

    name = forms.CharField(max_length=250, widget=forms.TextInput(attrs={"size": 45}))


class ContainerDescriptionForm(NonASCIIForm):

    description = forms.CharField(
        widget=forms.Textarea(attrs={"rows": 3, "cols": 39}), required=False
    )


class BaseAnnotationForm(NonASCIIForm):
    """
    This is the superclass of the various forms used for annotating single or
    multiple objects.
    All these forms use hidden fields to specify the object(s) currently being
    annotated.
    """

    def __init__(self, *args, **kwargs):
        super(BaseAnnotationForm, self).__init__(*args, **kwargs)

        images = "images" in kwargs["initial"] and kwargs["initial"]["images"] or list()
        if len(images) > 0:
            try:
                self.fields["image"] = ObjectModelMultipleChoiceField(
                    queryset=images,
                    initial=kwargs["initial"]["selected"]["images"],
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )
            except Exception:
                self.fields["image"] = ObjectModelMultipleChoiceField(
                    queryset=images,
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )

        datasets = (
            "datasets" in kwargs["initial"] and kwargs["initial"]["datasets"] or list()
        )
        if len(datasets) > 0:
            try:
                self.fields["dataset"] = ObjectModelMultipleChoiceField(
                    queryset=datasets,
                    initial=kwargs["initial"]["selected"]["datasets"],
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )
            except Exception:
                self.fields["dataset"] = ObjectModelMultipleChoiceField(
                    queryset=datasets,
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )

        projects = (
            "projects" in kwargs["initial"] and kwargs["initial"]["projects"] or list()
        )
        if len(projects) > 0:
            try:
                self.fields["project"] = ObjectModelMultipleChoiceField(
                    queryset=projects,
                    initial=kwargs["initial"]["selected"]["projects"],
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )
            except Exception:
                self.fields["project"] = ObjectModelMultipleChoiceField(
                    queryset=projects,
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )

        screens = (
            "screens" in kwargs["initial"] and kwargs["initial"]["screens"] or list()
        )
        if len(screens) > 0:
            try:
                self.fields["screen"] = ObjectModelMultipleChoiceField(
                    queryset=screens,
                    initial=kwargs["initial"]["selected"]["screens"],
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )
            except Exception:
                self.fields["screen"] = ObjectModelMultipleChoiceField(
                    queryset=screens,
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )

        plates = "plates" in kwargs["initial"] and kwargs["initial"]["plates"] or list()
        if len(plates) > 0:
            try:
                self.fields["plate"] = ObjectModelMultipleChoiceField(
                    queryset=plates,
                    initial=kwargs["initial"]["selected"]["plates"],
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )
            except Exception:
                self.fields["plate"] = ObjectModelMultipleChoiceField(
                    queryset=plates,
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )

        acquisitions = (
            "acquisitions" in kwargs["initial"]
            and kwargs["initial"]["acquisitions"]
            or list()
        )
        if len(acquisitions) > 0:
            try:
                self.fields["acquisition"] = ObjectModelMultipleChoiceField(
                    queryset=acquisitions,
                    initial=kwargs["initial"]["selected"]["acquisitions"],
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )
            except Exception:
                self.fields["acquisition"] = ObjectModelMultipleChoiceField(
                    queryset=acquisitions,
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )

        wells = "wells" in kwargs["initial"] and kwargs["initial"]["wells"] or list()
        if len(wells) > 0:
            try:
                self.fields["well"] = ObjectModelMultipleChoiceField(
                    queryset=wells,
                    initial=kwargs["initial"]["selected"]["wells"],
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )
            except Exception:
                self.fields["well"] = ObjectModelMultipleChoiceField(
                    queryset=wells,
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )

        shares = "shares" in kwargs["initial"] and kwargs["initial"]["shares"] or list()
        if len(shares) > 0:
            try:
                self.fields["share"] = ObjectModelMultipleChoiceField(
                    queryset=shares,
                    initial=kwargs["initial"]["selected"]["shares"],
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )
            except Exception:
                self.fields["share"] = ObjectModelMultipleChoiceField(
                    queryset=shares,
                    widget=forms.SelectMultiple(attrs={"size": 10}),
                    required=False,
                )


class TagsAnnotationForm(BaseAnnotationForm):
    """
    Form for annotating one or more objects with existing Tags or New tags
    """

    def __init__(self, *args, **kwargs):
        super(TagsAnnotationForm, self).__init__(*args, **kwargs)

    tags = forms.CharField(required=False, widget=forms.HiddenInput)

    def clean_tags(self):
        data = self.cleaned_data["tags"]
        if not data:
            return []
        try:
            data = map(int, data.split(","))
        except Exception:
            raise forms.ValidationError()
        return data


class NewTagsAnnotationForm(forms.Form):
    """Helper form for new tags"""

    tag = forms.CharField(required=True, widget=forms.HiddenInput)
    description = forms.CharField(required=False, widget=forms.HiddenInput)
    tagset = forms.IntegerField(min_value=1, required=False, widget=forms.HiddenInput)


NewTagsAnnotationFormSet = formset_factory(NewTagsAnnotationForm, extra=0)


class FilesAnnotationForm(BaseAnnotationForm):
    def __init__(self, *args, **kwargs):
        super(FilesAnnotationForm, self).__init__(*args, **kwargs)
        self.fields["files"] = AnnotationModelMultipleChoiceField(
            queryset=kwargs["initial"]["files"],
            widget=forms.SelectMultiple(attrs={"size": 8, "class": "existing"}),
            required=False,
        )

    annotation_file = forms.FileField(required=False)


class CommentAnnotationForm(BaseAnnotationForm):
    comment = forms.CharField(widget=forms.Textarea(attrs={"rows": 2, "cols": 39}))


class ActiveGroupForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(ActiveGroupForm, self).__init__(*args, **kwargs)
        try:
            self.fields["active_group"] = GroupModelChoiceField(
                queryset=kwargs["initial"]["mygroups"],
                initial=kwargs["initial"]["activeGroup"],
                empty_label=None,
                widget=forms.Select(
                    attrs={
                        "onchange": (
                            "window.location.href='"
                            + reverse(viewname="change_active_group")
                            + "?url="
                            + kwargs["initial"]["url"]
                            + "&active_group='"
                            "+this.options[this.selectedIndex].value"
                        )
                    }
                ),
            )
        except Exception:
            self.fields["active_group"] = GroupModelChoiceField(
                queryset=kwargs["initial"]["mygroups"],
                initial=kwargs["initial"]["activeGroup"],
                empty_label=None,
                widget=forms.Select(
                    attrs={
                        "onchange": (
                            "window.location.href='"
                            + reverse(viewname="change_active_group")
                            + "?active_group='"
                            "+this.options[this.selectedIndex].value"
                        )
                    }
                ),
            )
        self.fields.keyOrder = ["active_group"]


class WellIndexForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(WellIndexForm, self).__init__(*args, **kwargs)
        rmin, rmax = kwargs["initial"]["range"]
        choices = [(str(i), "Field#%i" % (i - rmin + 1)) for i in range(rmin, rmax + 1)]
        self.fields["index"] = forms.ChoiceField(
            choices=tuple(choices),
            widget=forms.Select(
                attrs={
                    "onchange": ("changeField(this.options[this.selectedIndex].value);")
                }
            ),
        )
        self.fields.keyOrder = ["index"]


###############################
# METADATA FORMS


def save_metadata(obj, name, options=False):
    s = "javascript:save_metadata(" + str(obj) + ", '" + name + "', "
    if options:
        s += "this.options[this.selectedIndex].value);"
    else:
        s += "this.value);"

    return s


def set_widget_attrs(field, set_class=True):
    field.widget.attrs["disabled"] = True
    if set_class:
        field.widget.attrs["class"] = "disabled-metadata"


class MetadataChannelForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MetadataChannelForm, self).__init__(*args, **kwargs)

        # Logical channel

        # Name
        logicalCh = kwargs["initial"]["logicalChannel"]
        try:
            if logicalCh is not None:
                self.fields["name"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={"size": 25, "onchange": save_metadata(logicalCh.id)}
                    ),
                    initial=logicalCh.name,
                    required=False,
                )
            else:
                self.fields["name"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["name"])
        except Exception:
            self.fields["name"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["name"])

        # excitationWave
        try:
            if logicalCh is not None:
                self.fields["excitationWave"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    initial=kwargs["initial"]["exWave"].getValue(),
                    label=("Excitation (%s)" % kwargs["initial"]["exWave"].getSymbol()),
                    required=False,
                )
            else:
                self.fields["excitationWave"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    label="Excitation",
                    required=False,
                )
            set_widget_attrs(self.fields["excitationWave"])
        except Exception:
            self.fields["excitationWave"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Excitation",
                required=False,
            )
            set_widget_attrs(self.fields["excitationWave"])

        # emissionWave
        try:
            if logicalCh is not None:
                self.fields["emissionWave"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    initial=kwargs["initial"]["emWave"].getValue(),
                    label=("Emission (%s)" % kwargs["initial"]["emWave"].getSymbol()),
                    required=False,
                )
            else:
                self.fields["emissionWave"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    label="Emission",
                    required=False,
                )
            set_widget_attrs(self.fields["emissionWave"])
        except Exception:
            self.fields["emissionWave"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Emission",
                required=False,
            )
            set_widget_attrs(self.fields["emissionWave"])

        # ndFilter
        try:
            if logicalCh is not None and logicalCh.ndFilter is not None:
                self.fields["ndFilter"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    initial=formatPercentFraction(logicalCh.ndFilter),
                    label="ND filter (%)",
                    required=False,
                )
            else:
                self.fields["ndFilter"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    label="ND filter (%)",
                    required=False,
                )
            set_widget_attrs(self.fields["ndFilter"], set_class=False)
        except Exception:
            self.fields["ndFilter"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="ND filter (%)",
                required=False,
            )
            set_widget_attrs(self.fields["ndFilter"], set_class=False)

        # pinHoleSize
        try:
            if logicalCh is not None and logicalCh.pinHoleSize is not None:
                self.fields["pinHoleSize"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    initial=logicalCh.pinHoleSize.getValue(),
                    label=("Pin hole size (%s)" % logicalCh.pinHoleSize.getSymbol()),
                    required=False,
                )
            else:
                self.fields["pinHoleSize"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    label="Pin hole size",
                    required=False,
                )
            set_widget_attrs(self.fields["pinHoleSize"], set_class=False)
        except Exception:
            self.fields["pinHoleSize"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Pin hole size",
                required=False,
            )
            set_widget_attrs(self.fields["pinHoleSize"], set_class=False)

        # fluor
        try:
            if logicalCh is not None:
                self.fields["fluor"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    initial=logicalCh.fluor,
                    required=False,
                )
            else:
                self.fields["fluor"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["fluor"], set_class=False)
        except Exception:
            self.fields["fluor"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["fluor"], set_class=False)

        # Illumination
        try:
            if logicalCh.getIllumination() is not None:
                self.fields["illumination"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["illuminations"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                logicalCh.id, "illumination", options=True
                            )
                        }
                    ),
                    initial=logicalCh.getIllumination(),
                    required=False,
                )
            else:
                self.fields["illumination"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["illuminations"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                logicalCh.id, "illumination", options=True
                            )
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["illumination"], set_class=False)
        except Exception:
            self.fields["illumination"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["illumination"], set_class=False)

        # contrastMethods
        try:
            if logicalCh.contrastMethod is not None:
                self.fields["contrastMethod"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["contrastMethods"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                logicalCh.id, "contrastMethod", options=True
                            )
                        }
                    ),
                    initial=logicalCh.getContrastMethod(),
                    label="Contrast method",
                    required=False,
                )
            else:
                self.fields["contrastMethod"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["contrastMethods"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                logicalCh.id, "contrastMethod", options=True
                            )
                        }
                    ),
                    label="Contrast method",
                    required=False,
                )
            set_widget_attrs(self.fields["contrastMethod"])
        except Exception:
            self.fields["contrastMethod"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Contrast method",
                required=False,
            )
            set_widget_attrs(self.fields["contrastMethod"])

        # Mode
        try:
            if logicalCh.getMode() is not None:
                self.fields["mode"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["modes"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                logicalCh.id, "mode", options=True
                            )
                        }
                    ),
                    initial=logicalCh.getMode().value,
                    required=False,
                )
            else:
                self.fields["mode"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["modes"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                logicalCh.id, "mode", options=True
                            )
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["mode"])
        except Exception:
            self.fields["mode"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["mode"])

        # pockelCellSetting
        try:
            if logicalCh.pockelCellSetting is not None:
                self.fields["pockelCellSetting"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    initial=logicalCh.pockelCellSetting,
                    label="Pockel cell",
                    required=False,
                )
            else:
                self.fields["pockelCellSetting"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(logicalCh.id, "name"),
                        }
                    ),
                    label="Pockel cell",
                    required=False,
                )
            set_widget_attrs(self.fields["pockelCellSetting"])
        except Exception:
            self.fields["pockelCellSetting"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Pockel cell",
                required=False,
            )
            set_widget_attrs(self.fields["pockelCellSetting"])

        self.fields.keyOrder = [
            "name",
            "excitationWave",
            "emissionWave",
            "ndFilter",
            "pinHoleSize",
            "fluor",
            "illumination",
            "contrastMethod",
            "mode",
            "pockelCellSetting",
        ]


class MetadataDichroicForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MetadataDichroicForm, self).__init__(*args, **kwargs)

        # Manufacturer
        try:
            if kwargs["initial"]["dichroic"].manufacturer is not None:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["dichroic"].id, "manufacturer"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["dichroic"].manufacturer,
                    required=False,
                )
            else:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["dichroic"].id, "manufacturer"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["manufacturer"])
        except Exception:
            self.fields["manufacturer"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["manufacturer"])

        # Model
        try:
            if kwargs["initial"]["dichroic"].model is not None:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["dichroic"].id, "model"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["dichroic"].model,
                    required=False,
                )
            else:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["dichroic"].id, "model"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["model"])
        except Exception:
            self.fields["model"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["model"])

        # Serial number
        try:
            if kwargs["initial"]["dichroic"].serialNumber is not None:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["dichroic"].serialNumber,
                                "serialNumber",
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["dichroic"].serialNumber,
                    label="Serial number",
                    required=False,
                )
            else:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["dichroic"].serialNumber,
                                "serialNumber",
                            ),
                        }
                    ),
                    label="Serial number",
                    required=False,
                )
            set_widget_attrs(self.fields["serialNumber"])
        except Exception:
            self.fields["serialNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Serial number",
                required=False,
            )
            set_widget_attrs(self.fields["serialNumber"])

        # Lot number
        try:
            if kwargs["initial"]["dichroic"].lotNumber is not None:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["dichroic"].lotNumber, "lotNumber"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["dichroic"].lotNumber,
                    label="Lot number",
                    required=False,
                )
            else:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["dichroic"].lotNumber, "lotNumber"
                            ),
                        }
                    ),
                    label="Lot number",
                    required=False,
                )
            set_widget_attrs(self.fields["lotNumber"])
        except Exception:
            self.fields["lotNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Lot number",
                required=False,
            )
            set_widget_attrs(self.fields["lotNumber"])

        self.fields.keyOrder = ["model", "manufacturer", "serialNumber", "lotNumber"]


class MetadataMicroscopeForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MetadataMicroscopeForm, self).__init__(*args, **kwargs)

        # Model
        try:
            if kwargs["initial"]["microscope"].model is not None:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["microscope"].id, "model"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["microscope"].model,
                    required=False,
                )
            else:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["microscope"].id, "model"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["model"])
        except Exception:
            self.fields["model"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["model"])

        # Manufacturer
        try:
            if kwargs["initial"]["microscope"].manufacturer is not None:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["microscope"].id, "manufacturer"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["microscope"].manufacturer,
                    required=False,
                )
            else:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["microscope"].id, "manufacturer"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["manufacturer"])
        except Exception:
            self.fields["manufacturer"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["manufacturer"])

        # Serial number
        try:
            if kwargs["initial"]["microscope"].serialNumber is not None:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["microscope"].id, "lotNumber"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["microscope"].serialNumber,
                    label="Serial number",
                    required=False,
                )
            else:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["microscope"].id, "lotNumber"
                            ),
                        }
                    ),
                    label="Serial number",
                    required=False,
                )
            set_widget_attrs(self.fields["serialNumber"])
        except Exception:
            self.fields["serialNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Serial number",
                required=False,
            )
            set_widget_attrs(self.fields["serialNumber"])

        # Lot number
        try:
            if kwargs["initial"]["microscope"].lotNumber is not None:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["microscope"].id, "lotNumber"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["microscope"].lotNumber,
                    label="Lot number",
                    required=False,
                )
            else:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["microscope"].id, "lotNumber"
                            ),
                        }
                    ),
                    label="Serial number",
                    required=False,
                )
            set_widget_attrs(self.fields["lotNumber"])
        except Exception:
            self.fields["lotNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Serial number",
                required=False,
            )
            set_widget_attrs(self.fields["lotNumber"])

        # Type
        try:
            if kwargs["initial"]["microscope"].getMicroscopeType() is not None:
                self.fields["type"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["microscopeTypes"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["microscope"].id, "type", options=True
                            )
                        }
                    ),
                    initial=kwargs["initial"]["microscope"].getMicroscopeType().value,
                    required=False,
                )
            else:
                self.fields["type"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["microscopeTypes"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["microscope"].id, "type", options=True
                            )
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["type"])
        except Exception:
            self.fields["type"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["type"])

        self.fields.keyOrder = [
            "model",
            "manufacturer",
            "serialNumber",
            "lotNumber",
            "type",
        ]


class MetadataObjectiveForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MetadataObjectiveForm, self).__init__(*args, **kwargs)

        # Model
        try:
            if kwargs["initial"]["objective"].model is not None:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "model"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["objective"].model,
                    required=False,
                )
            else:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "model"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["model"])
        except Exception:
            self.fields["model"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["model"])

        # Manufacturer
        try:
            if kwargs["initial"]["objective"].manufacturer is not None:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "manufacturer"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["objective"].manufacturer,
                    required=False,
                )
            else:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "manufacturer"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["manufacturer"])
        except Exception:
            self.fields["manufacturer"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["manufacturer"])

        # Serial Number
        try:
            if kwargs["initial"]["objective"].serialNumber is not None:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "serialNumber"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["objective"].serialNumber,
                    label="Serial number",
                    required=False,
                )
            else:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "serialNumber"
                            ),
                        }
                    ),
                    label="Serial number",
                    required=False,
                )
            set_widget_attrs(self.fields["serialNumber"])
        except Exception:
            self.fields["serialNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Serial number",
                required=False,
            )
            set_widget_attrs(self.fields["serialNumber"])

        # Lot number
        try:
            if kwargs["initial"]["objective"].lotNumber is not None:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].lotNumber, "lotNumber"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["objective"].lotNumber,
                    label="Lot number",
                    required=False,
                )
            else:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["logicalchannel"]
                                .getObjective()
                                .lotNumber,
                                "lotNumber",
                            ),
                        }
                    ),
                    label="Lot number",
                    required=False,
                )
            set_widget_attrs(self.fields["lotNumber"])
        except Exception:
            self.fields["lotNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Lot number",
                required=False,
            )
            set_widget_attrs(self.fields["lotNumber"])

        # Nominal Magnification
        try:
            if kwargs["initial"]["objective"].nominalMagnification is not None:
                self.fields["nominalMagnification"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id,
                                "nominalMagnification",
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["objective"].nominalMagnification,
                    label="Nominal magnification",
                    required=False,
                )
            else:
                self.fields["nominalMagnification"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id,
                                "nominalMagnification",
                            ),
                        }
                    ),
                    label="Nominal magnification",
                    required=False,
                )
            set_widget_attrs(self.fields["nominalMagnification"])
        except Exception:
            self.fields["nominalMagnification"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Nominal magnification",
                required=False,
            )
            set_widget_attrs(self.fields["nominalMagnification"])

        # Calibrated Magnification
        try:
            if kwargs["initial"]["objective"].calibratedMagnification is not None:
                self.fields["calibratedMagnification"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id,
                                "calibratedMagnification",
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["objective"].calibratedMagnification,
                    label="Calibrated magnification",
                    required=False,
                )
            else:
                self.fields["calibratedMagnification"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id,
                                "calibratedMagnification",
                            ),
                        }
                    ),
                    label="Calibrated magnification",
                    required=False,
                )
            set_widget_attrs(self.fields["calibratedMagnification"])
        except Exception:
            self.fields["calibratedMagnification"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Calibrated magnification",
                required=False,
            )
            set_widget_attrs(self.fields["calibratedMagnification"])

        # Lens NA
        try:
            if kwargs["initial"]["objective"].lensNA is not None:
                self.fields["lensNA"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "lensNA"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["objective"].lensNA,
                    label="Lens NA",
                    required=False,
                )
            else:
                self.fields["lensNA"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "lensNA"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["lensNA"])
        except Exception:
            self.fields["lensNA"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Lens NA",
                required=False,
            )
            set_widget_attrs(self.fields["lensNA"])

        # Immersion
        try:
            if kwargs["initial"]["objective"].getImmersion() is not None:
                self.fields["immersion"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["immersions"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id,
                                "immersion",
                                options=True,
                            )
                        }
                    ),
                    initial=kwargs["initial"]["objective"].getImmersion().value,
                    required=False,
                )
            else:
                self.fields["immersion"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["immersions"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id,
                                "immersion",
                                options=True,
                            )
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["immersion"])
        except Exception:
            self.fields["immersion"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["immersion"])

        # Correction
        try:
            if kwargs["initial"]["objective"].getCorrection() is not None:
                self.fields["correction"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["corrections"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id,
                                "correction",
                                options=True,
                            )
                        }
                    ),
                    initial=kwargs["initial"]["objective"].getCorrection().value,
                    required=False,
                )
            else:
                self.fields["correction"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["corrections"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id,
                                "correction",
                                options=True,
                            )
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["correction"])

        except Exception:
            self.fields["correction"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["correction"])

        # Working Distance
        try:
            if kwargs["initial"]["objective"].workingDistance is not None:
                self.fields["workingDistance"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "workingDistance"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["objective"].workingDistance.getValue(),
                    label=(
                        "Working distance (%s)"
                        % kwargs["initial"]["objective"].workingDistance.getSymbol()
                    ),
                    required=False,
                )
            else:
                self.fields["workingDistance"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "workingDistance"
                            ),
                        }
                    ),
                    label="Working distance",
                    required=False,
                )
            set_widget_attrs(self.fields["workingDistance"])
        except Exception:
            self.fields["workingDistance"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Working distance",
                required=False,
            )
            set_widget_attrs(self.fields["workingDistance"])

        # Iris
        try:
            if kwargs["initial"]["objective"].getIris() is not None:
                self.fields["iris"] = forms.ChoiceField(
                    choices=self.BOOLEAN_CHOICES,
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "iris", options=True
                            )
                        }
                    ),
                    initial=kwargs["initial"]["objective"].getIris().value,
                    required=False,
                )
            else:
                self.fields["iris"] = forms.ChoiceField(
                    choices=self.BOOLEAN_CHOICES,
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["objective"].id, "iris", options=True
                            )
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["iris"])
        except Exception:
            self.fields["iris"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["iris"])

        self.fields.keyOrder = [
            "model",
            "manufacturer",
            "serialNumber",
            "lotNumber",
            "nominalMagnification",
            "calibratedMagnification",
            "lensNA",
            "immersion",
            "correction",
            "workingDistance",
            "iris",
        ]


class MetadataObjectiveSettingsForm(MetadataObjectiveForm):

    BOOLEAN_CHOICES = (
        ("", "---------"),
        ("True", "True"),
        ("False", "False"),
    )

    def __init__(self, *args, **kwargs):
        super(MetadataObjectiveSettingsForm, self).__init__(*args, **kwargs)

        # Objective Settings

        # Correction Collar
        try:
            if kwargs["initial"]["objectiveSettings"].correctionCollar is not None:
                self.fields["correctionCollar"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objectiveSettings"].id,
                                "correctionCollar",
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["objectiveSettings"].correctionCollar,
                    label="Correction collar",
                    required=False,
                )
            else:
                self.fields["correctionCollar"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objectiveSettings"].id,
                                "correctionCollar",
                            ),
                        }
                    ),
                    label="Correction collar",
                    required=False,
                )
            set_widget_attrs(self.fields["correctionCollar"])
        except Exception:
            self.fields["correctionCollar"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Correction collar",
                required=False,
            )
            set_widget_attrs(self.fields["correctionCollar"])

        # Medium
        try:
            if kwargs["initial"]["objectiveSettings"].getMedium() is not None:
                self.fields["medium"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["mediums"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["objectiveSettings"].id,
                                "medium",
                                options=True,
                            )
                        }
                    ),
                    initial=kwargs["initial"]["objectiveSettings"].getMedium().value,
                    required=False,
                )
            else:
                self.fields["medium"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["mediums"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["objectiveSettings"].id,
                                "medium",
                                options=True,
                            )
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["medium"])
        except Exception:
            self.fields["medium"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["medium"])

        # Refractive Index
        try:
            if kwargs["initial"]["objectiveSettings"].refractiveIndex is not None:
                self.fields["refractiveIndex"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objectiveSettings"].id,
                                "refractiveIndex",
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["objectiveSettings"].refractiveIndex,
                    label="Refractive index",
                    required=False,
                )
            else:
                self.fields["refractiveIndex"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["objectiveSettings"].id,
                                "refractiveIndex",
                            ),
                        }
                    ),
                    label="Refractive index",
                    required=False,
                )
            set_widget_attrs(self.fields["refractiveIndex"])
        except Exception:
            self.fields["refractiveIndex"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Refractive index",
                required=False,
            )
            set_widget_attrs(self.fields["refractiveIndex"])

        self.fields.keyOrder = [
            "model",
            "manufacturer",
            "serialNumber",
            "lotNumber",
            "nominalMagnification",
            "calibratedMagnification",
            "lensNA",
            "immersion",
            "correction",
            "workingDistance",
            "iris",
            "correctionCollar",
            "medium",
            "refractiveIndex",
        ]


class MetadataFilterForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MetadataFilterForm, self).__init__(*args, **kwargs)

        # Filter

        # Manufacturer
        try:
            if kwargs["initial"]["filter"].manufacturer is not None:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "manufacturer"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["filter"].manufacturer,
                    required=False,
                )
            else:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "manufacturer"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["manufacturer"])
        except Exception:
            self.fields["manufacturer"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["manufacturer"])

        # Model
        try:
            if kwargs["initial"]["filter"].model is not None:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "model"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["filter"].model,
                    required=False,
                )
            else:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "model"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["model"])
        except Exception:
            self.fields["model"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["model"])

        # Serial Number
        try:
            if kwargs["initial"]["filter"].serialNumber is not None:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "serialNumber"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["filter"].serialNumber,
                    label="Serial number",
                    required=False,
                )
            else:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "serialNumber"
                            ),
                        }
                    ),
                    label="Serial number",
                    required=False,
                )
            set_widget_attrs(self.fields["serialNumber"])
        except Exception:
            self.fields["serialNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Serial number",
                required=False,
            )
            set_widget_attrs(self.fields["serialNumber"])

        # Lot number
        try:
            if kwargs["initial"]["filter"].lotNumber is not None:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "lotNumber"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["filter"].lotNumber,
                    label="Lot number",
                    required=False,
                )
            else:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "lotNumber"
                            ),
                        }
                    ),
                    label="Lot number",
                    required=False,
                )
            set_widget_attrs(self.fields["lotNumber"])
        except Exception:
            self.fields["lotNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Lot number",
                required=False,
            )
            set_widget_attrs(self.fields["lotNumber"])

        # Filter wheel
        try:
            if kwargs["initial"]["filter"].filterWheel is not None:
                self.fields["filterWheel"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "filterWheel"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["filter"].filterWheel,
                    label="Filter wheel",
                    required=False,
                )
            else:
                self.fields["filterWheel"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "filterWheel"
                            ),
                        }
                    ),
                    label="Filter wheel",
                    required=False,
                )
            set_widget_attrs(self.fields["filterWheel"])
        except Exception:
            self.fields["filterWheel"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Filter wheel",
                required=False,
            )
            set_widget_attrs(self.fields["filterWheel"])

        # Type
        try:
            if kwargs["initial"]["filter"].getFilterType() is not None:
                self.fields["type"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["types"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "type", options=True
                            )
                        }
                    ),
                    initial=kwargs["initial"]["filter"].getFilterType().value,
                    required=False,
                )
            else:
                self.fields["type"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["types"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "type", options=True
                            )
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["type"])
        except Exception:
            self.fields["type"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["type"])

        # Cut in
        tr = kwargs["initial"]["filter"].getTransmittanceRange()
        try:
            if tr is not None and tr.cutIn is not None:
                self.fields["cutIn"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "cutIn"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["filter"]
                    .getTransmittanceRange()
                    .cutIn.getValue(),
                    label="Cut in (%s)" % tr.cutIn.getSymbol(),
                    required=False,
                )
            else:
                self.fields["cutIn"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "cutIn"
                            ),
                        }
                    ),
                    label="Cut in",
                    required=False,
                )
            set_widget_attrs(self.fields["cutIn"])
        except Exception:
            self.fields["cutIn"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Cut in",
                required=False,
            )
            set_widget_attrs(self.fields["cutIn"])

        # Cut out
        try:
            if tr is not None and tr.cutOut is not None:
                self.fields["cutOut"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "cutOut"
                            ),
                        }
                    ),
                    initial=tr.cutOut.getValue(),
                    label="Cut out (%s)" % tr.cutOut.getSymbol(),
                    required=False,
                )
            else:
                self.fields["cutOut"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "cutOut"
                            ),
                        }
                    ),
                    label="Cut out",
                    required=False,
                )
            set_widget_attrs(self.fields["cutOut"])
        except Exception:
            self.fields["cutOut"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Cut out",
                required=False,
            )
            set_widget_attrs(self.fields["cutOut"])

        # Cut in tolerance
        try:
            if tr is not None and tr.cutInTolerance is not None:
                self.fields["cutInTolerance"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "cutInTolerance"
                            ),
                        }
                    ),
                    initial=tr.cutInTolerance.getValue(),
                    label=("Cut in tolerance (%s)" % tr.cutInTolerance.getSymbol()),
                    required=False,
                )
            else:
                self.fields["cutInTolerance"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "cutInTolerance"
                            ),
                        }
                    ),
                    label="Cut in tolerance",
                    required=False,
                )
            set_widget_attrs(self.fields["cutInTolerance"])
        except Exception:
            self.fields["cutInTolerance"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Cut in tolerance",
                required=False,
            )
            set_widget_attrs(self.fields["cutInTolerance"])

        # Cut on tolerance
        try:
            if tr is not None and tr.cutOutTolerance is not None:
                self.fields["cutOutTolerance"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "cutOut"
                            ),
                        }
                    ),
                    initial=tr.cutOutTolerance.getValue(),
                    label=("Cut out tolerance (%s)" % tr.cutOutTolerance.getSymbol()),
                    required=False,
                )
            else:
                self.fields["cutOutTolerance"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "cutOut"
                            ),
                        }
                    ),
                    label="Cut out tolerance",
                    required=False,
                )
            set_widget_attrs(self.fields["cutOutTolerance"])
        except Exception:
            self.fields["cutOutTolerance"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Cut out tolerance",
                required=False,
            )
            set_widget_attrs(self.fields["cutOutTolerance"])

        # Transmittance
        try:
            if kwargs["initial"]["filter"].transmittanceRange is not None:
                self.fields["transmittance"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "transmittance"
                            ),
                        }
                    ),
                    initial=formatPercentFraction(
                        kwargs["initial"]["filter"]
                        .getTransmittanceRange()
                        .transmittance
                    ),
                    label="Transmittance (%)",
                    required=False,
                )
            else:
                self.fields["transmittance"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["filter"].id, "transmittance"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["transmittance"])
        except Exception:
            self.fields["transmittance"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["transmittance"])

        self.fields.keyOrder = [
            "model",
            "manufacturer",
            "serialNumber",
            "lotNumber",
            "type",
            "filterWheel",
            "cutIn",
            "cutOut",
            "cutInTolerance",
            "cutOutTolerance",
            "transmittance",
        ]


class MetadataDetectorForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MetadataDetectorForm, self).__init__(*args, **kwargs)

        detSet = kwargs["initial"]["detectorSettings"]
        detector = kwargs["initial"]["detector"]

        # Manufacturer
        try:
            if detector is not None:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "manufacturer"),
                        }
                    ),
                    initial=detector.manufacturer,
                    required=False,
                )
            else:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "manufacturer"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["manufacturer"])
        except Exception:
            self.fields["manufacturer"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["manufacturer"])

        # Model
        try:
            if detector is not None:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "model"),
                        }
                    ),
                    initial=detector.model,
                    required=False,
                )
            else:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "model"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["model"])
        except Exception:
            self.fields["model"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["model"])

        # SN
        try:
            if detector is not None:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "serialNumber"),
                        }
                    ),
                    initial=detector.serialNumber,
                    required=False,
                )
            else:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "serialNumber"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["serialNumber"])
        except Exception:
            self.fields["serialNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["serialNumber"])

        # Lot number (NB. Untill OMERO model is updated in 4.3, this will
        # throw since lotNumber is not yet supported)
        try:
            if detector is not None:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "lotNumber"),
                        }
                    ),
                    initial=detector.lotNumber,
                    required=False,
                )
            else:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "lotNumber"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["lotNumber"])
        except Exception:
            self.fields["lotNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["lotNumber"])

        # Type
        try:
            if detector.getDetectorType() is not None:
                self.fields["type"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["types"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(detector.id, "type", options=True)
                        }
                    ),
                    initial=detector.getDetectorType().value,
                    required=False,
                )
            else:
                self.fields["type"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["types"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(detector.id, "type", options=True)
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["type"])
        except Exception:
            self.fields["type"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["type"])

        # Gain
        try:
            if detSet is not None:
                self.fields["gain"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={"size": 25, "onchange": save_metadata(detSet.id, "gain")}
                    ),
                    initial=detSet.gain,
                    required=False,
                )
            elif detector is not None:
                self.fields["gain"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "gain"),
                        }
                    ),
                    initial=detector.gain,
                    required=False,
                )
            else:
                self.fields["gain"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={"size": 25, "onchange": save_metadata(detSet.id, "gain")}
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["gain"])
        except Exception:
            self.fields["gain"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["gain"])

        # Voltage
        try:
            if detSet is not None and detSet.voltage is not None:
                self.fields["voltage"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detSet.id, "voltage"),
                        }
                    ),
                    initial=detSet.voltage.getValue(),
                    label="Voltage (%s)" % detSet.voltage.getSymbol(),
                    required=False,
                )
            elif detector is not None:
                self.fields["voltage"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "voltage"),
                        }
                    ),
                    initial=detector.voltage.getValue(),
                    label="Voltage (%s)" % detector.voltage.getSymbol(),
                    required=False,
                )
            else:
                self.fields["voltage"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detSet.id, "voltage"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["voltage"])
        except Exception:
            self.fields["voltage"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["voltage"])

        # Offset
        try:
            if detSet is not None:
                self.fields["offsetValue"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detSet.id, "offsetValue"),
                        }
                    ),
                    initial=detSet.offsetValue,
                    label="Offset",
                    required=False,
                )
            elif detector is not None:
                self.fields["offsetValue"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "offsetValue"),
                        }
                    ),
                    initial=detector.offsetValue,
                    label="Offset",
                    required=False,
                )
            else:
                self.fields["offsetValue"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "offsetValue"),
                        }
                    ),
                    label="Offset",
                    required=False,
                )
            set_widget_attrs(self.fields["offsetValue"])
        except Exception:
            self.fields["offsetValue"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Offset",
                required=False,
            )
            set_widget_attrs(self.fields["offsetValue"])

        # Zoom
        try:
            if detector is not None:
                self.fields["zoom"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "voltage"),
                        }
                    ),
                    initial=detector.zoom,
                    required=False,
                )
            else:
                self.fields["zoom"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "voltage"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["zoom"])
        except Exception:
            self.fields["zoom"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["zoom"])

        # Amplification gain
        try:
            if detector is not None:
                self.fields["amplificationGain"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "amplificationGain"),
                        }
                    ),
                    initial=detector.amplificationGain,
                    label="Amplification gain",
                    required=False,
                )
            else:
                self.fields["amplificationGain"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detector.id, "amplificationGain"),
                        }
                    ),
                    label="Amplification gain",
                    required=False,
                )
            set_widget_attrs(self.fields["amplificationGain"])
        except Exception:
            self.fields["amplificationGain"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Amplification gain",
                required=False,
            )
            set_widget_attrs(self.fields["amplificationGain"])

        # Read out rate
        try:
            if detSet is not None and detSet.readOutRate is not None:
                self.fields["readOutRate"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detSet.id, "readOutRate"),
                        }
                    ),
                    initial=detSet.readOutRate.getValue(),
                    label=("Read out rate (%s)" % detSet.readOutRate.getSymbol()),
                    required=False,
                )
            else:
                self.fields["readOutRate"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(detSet.id, "readOutRate"),
                        }
                    ),
                    label="Read out rate",
                    required=False,
                )
            set_widget_attrs(self.fields["readOutRate"])
        except Exception:
            self.fields["readOutRate"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Read out rate",
                required=False,
            )
            set_widget_attrs(self.fields["readOutRate"])

        # Binning
        try:
            if detSet is not None:
                self.fields["binning"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["binnings"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(detSet.id, "type", options=True)
                        }
                    ),
                    initial=detSet.getBinning().value,
                    required=False,
                )
            else:
                self.fields["binning"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["binnings"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(detSet.id, "type", options=True)
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["binning"])
        except Exception:
            self.fields["binning"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["binning"])

        self.fields.keyOrder = [
            "model",
            "manufacturer",
            "serialNumber",
            "lotNumber",
            "type",
            "gain",
            "voltage",
            "offsetValue",
            "zoom",
            "amplificationGain",
            "readOutRate",
            "binning",
        ]


class MetadataLightSourceForm(forms.Form):

    BOOLEAN_CHOICES = (
        ("", "---------"),
        ("True", "True"),
        ("False", "False"),
    )

    def __init__(self, *args, **kwargs):
        super(MetadataLightSourceForm, self).__init__(*args, **kwargs)

        lightSource = kwargs["initial"]["lightSource"]
        lightSourceSettings = None
        if "lightSourceSettings" in kwargs["initial"]:
            lightSourceSettings = kwargs["initial"]["lightSourceSettings"]

        self.lightSourceType = lightSource.OMERO_CLASS

        # Manufacturer
        try:
            if lightSource.manufacturer is not None:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "model"),
                        }
                    ),
                    initial=lightSource.manufacturer,
                    required=False,
                )
            else:
                self.fields["manufacturer"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "model"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["manufacturer"])
        except Exception:
            self.fields["manufacturer"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["manufacturer"])

        # Model
        try:
            if lightSource.model is not None:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "model"),
                        }
                    ),
                    initial=lightSource.model,
                    required=False,
                )
            else:
                self.fields["model"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "model"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["model"])
        except Exception:
            self.fields["model"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["model"])

        # Serial Number
        try:
            if lightSource.serialNumber is not None:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "serialNumber"),
                        }
                    ),
                    initial=lightSource.serialNumber,
                    label="Serial number",
                    required=False,
                )
            else:
                self.fields["serialNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "serialNumber"),
                        }
                    ),
                    label="Serial number",
                    required=False,
                )
            set_widget_attrs(self.fields["serialNumber"])
        except Exception:
            self.fields["serialNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Serial number",
                required=False,
            )
            set_widget_attrs(self.fields["serialNumber"])

        # Lot Number
        try:
            if lightSource.lotNumber is not None:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "lotNumber"),
                        }
                    ),
                    initial=lightSource.lotNumber,
                    label="Lot number",
                    required=False,
                )
            else:
                self.fields["lotNumber"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "lotNumber"),
                        }
                    ),
                    label="Lot number",
                    required=False,
                )
            set_widget_attrs(self.fields["lotNumber"])
        except Exception:
            self.fields["lotNumber"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Lot number",
                required=False,
            )
            set_widget_attrs(self.fields["lotNumber"])

        # Power
        try:
            if lightSource.power is not None:
                self.fields["power"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "power"),
                        }
                    ),
                    initial=lightSource.power.getValue(),
                    label="Power (%s)" % lightSource.power.getSymbol(),
                    required=False,
                )
            else:
                self.fields["power"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "power"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["power"])
        except Exception:
            self.fields["power"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["power"])

        # Type
        try:
            if lightSource.getLightSourceType() is not None:
                self.fields["lstype"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["lstypes"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                lightSource.id, "type", options=True
                            )
                        }
                    ),
                    label="Type",
                    initial=lightSource.getLightSourceType().value,
                    required=False,
                )
            else:
                self.fields["lstype"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["lstypes"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                lightSource.id, "type", options=True
                            )
                        }
                    ),
                    label="Type",
                    required=False,
                )
            set_widget_attrs(self.fields["lstype"])
        except Exception:
            self.fields["lstype"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Type",
                required=False,
            )
            set_widget_attrs(self.fields["lstype"])

        # Pump (laser only)
        try:
            # Will throw exception for non-Laser lightsources.
            pump = lightSource.getPump()
            pumpType = pump.OMERO_CLASS  # E.g. 'Arc'
            pumpModel = pump.getModel()
            pumpValue = "%s: %s" % (pumpType, pumpModel)
            self.fields["pump"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial=pumpValue,
                required=False,
            )
        except Exception:
            # Not a Laser - don't show Pump
            self.fields["pump"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
        set_widget_attrs(self.fields["pump"])

        # Medium
        try:
            if lightSource.getLaserMedium() is not None:
                self.fields["lmedium"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["mediums"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                lightSource.id, "medium", options=True
                            )
                        }
                    ),
                    initial=lightSource.getLaserMedium().value,
                    label="Medium",
                    required=False,
                )
            else:
                self.fields["lmedium"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["mediums"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                lightSource.id, "medium", options=True
                            )
                        }
                    ),
                    label="Medium",
                    required=False,
                )
            set_widget_attrs(self.fields["lmedium"])
        except Exception:
            self.fields["lmedium"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Medium",
                required=False,
            )
            set_widget_attrs(self.fields["lmedium"])

        # Wavelength
        try:
            if (
                lightSourceSettings is not None
                and lightSourceSettings.wavelength is not None
            ):
                self.fields["wavelength"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "wavelength"),
                        }
                    ),
                    initial=lightSourceSettings.wavelength.getValue(),
                    label=(
                        "Wavelength (%s)" % lightSourceSettings.wavelength.getSymbol()
                    ),
                    required=False,
                )
            elif lightSource.wavelength is not None:
                self.fields["wavelength"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "wavelength"),
                        }
                    ),
                    initial=lightSource.wavelength.getValue(),
                    label=("Wavelength (%s)" % lightSource.wavelength.getSymbol()),
                    required=False,
                )
            else:
                self.fields["wavelength"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "wavelength"),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["wavelength"])
        except Exception:
            self.fields["wavelength"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["wavelength"])

        # FrequencyMultiplication
        try:
            if lightSource.frequencyMultiplication is not None:
                self.fields["frequencyMultiplication"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                lightSource.id, "frequencyMultiplication"
                            ),
                        }
                    ),
                    initial=lightSource.frequencyMultiplication,
                    label="Frequency Multiplication",
                    required=False,
                )
            else:
                self.fields["frequencyMultiplication"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                lightSource.id, "frequencyMultiplication"
                            ),
                        }
                    ),
                    label="Frequency Multiplication",
                    required=False,
                )
            set_widget_attrs(self.fields["frequencyMultiplication"])
        except Exception:
            self.fields["frequencyMultiplication"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Frequency Multiplication",
                required=False,
            )
            set_widget_attrs(self.fields["frequencyMultiplication"])

        # Tuneable
        try:
            if lightSource.tuneable is not None:
                self.fields["tuneable"] = forms.ChoiceField(
                    choices=self.BOOLEAN_CHOICES,
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                lightSource.id, "tuneable", options=True
                            )
                        }
                    ),
                    initial=lightSource.tuneable,
                    required=False,
                )
            else:
                self.fields["tuneable"] = forms.ChoiceField(
                    choices=self.BOOLEAN_CHOICES,
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                lightSource.id, "tuneable", options=True
                            )
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["tuneable"])
        except Exception:
            self.fields["tuneable"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["tuneable"])

        # Pulse
        try:
            if lightSource.pulse is not None:
                self.fields["pulse"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["pulses"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                lightSource.id, "pulse", options=True
                            )
                        }
                    ),
                    initial=lightSource.pulse,
                    required=False,
                )
            else:
                self.fields["pulse"] = MetadataModelChoiceField(
                    queryset=kwargs["initial"]["pulses"],
                    empty_label="Not set",
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                lightSource.id, "pulse", options=True
                            )
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["pulse"])
        except Exception:
            self.fields["pulse"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["pulse"])

        # Repetition Rate
        try:
            if lightSource.repetitionRate is not None:
                self.fields["repetitionRate"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "repetitionRate"),
                        }
                    ),
                    initial=lightSource.repetitionRate.getValue(),
                    label=(
                        "Repetition rate (%s)" % lightSource.repetitionRate.getSymbol()
                    ),
                    required=False,
                )
            else:
                self.fields["repetitionRate"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(lightSource.id, "repetitionRate"),
                        }
                    ),
                    label="Repetition rate",
                    required=False,
                )
            set_widget_attrs(self.fields["repetitionRate"])
        except Exception:
            self.fields["repetitionRate"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Repetition rate",
                required=False,
            )
            set_widget_attrs(self.fields["repetitionRate"])

        # Pockel Cell
        try:
            if lightSource.pockelCell is not None:
                self.fields["pockelCell"] = forms.ChoiceField(
                    choices=self.BOOLEAN_CHOICES,
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                lightSource.id, "pockelCell", options=True
                            )
                        }
                    ),
                    initial=lightSource.pockelCell,
                    label="Pockel Cell",
                    required=False,
                )
            else:
                self.fields["pockelCell"] = forms.ChoiceField(
                    choices=self.BOOLEAN_CHOICES,
                    widget=forms.Select(
                        attrs={
                            "onchange": save_metadata(
                                lightSource.id, "pockelCell", options=True
                            )
                        }
                    ),
                    label="Pockel Cell",
                    required=False,
                )
            set_widget_attrs(self.fields["pockelCell"])
        except Exception:
            self.fields["pockelCell"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Pockel Cell",
                required=False,
            )
            set_widget_attrs(self.fields["pockelCell"])

        # Attenuation
        if (
            lightSourceSettings is not None
            and lightSourceSettings.attenuation is not None
        ):
            self.fields["attenuation"] = forms.CharField(
                max_length=100,
                widget=forms.TextInput(
                    attrs={
                        "size": 25,
                        "onchange": save_metadata(
                            lightSourceSettings.id, "attenuation"
                        ),
                    }
                ),
                initial=formatPercentFraction(lightSourceSettings.attenuation),
                label="Attenuation (%)",
                required=False,
            )
        else:
            self.fields["attenuation"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
        set_widget_attrs(self.fields["attenuation"])

        self.fields.keyOrder = [
            "model",
            "manufacturer",
            "serialNumber",
            "lotNumber",
            "power",
            "lstype",
            "pump",
            "lmedium",
            "wavelength",
            "frequencyMultiplication",
            "tuneable",
            "pulse",
            "repetitionRate",
            "pockelCell",
            "attenuation",
        ]


class MetadataEnvironmentForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MetadataEnvironmentForm, self).__init__(*args, **kwargs)

        # Imaging environment

        imagingEnv = kwargs["initial"]["image"].getImagingEnvironment()
        # Temperature
        try:
            if imagingEnv.temperature is not None:
                self.fields["temperature"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "temperature"
                            ),
                        }
                    ),
                    initial=imagingEnv.temperature.getValue(),
                    label=("Temperature (%s)" % imagingEnv.temperature.getSymbol()),
                    required=False,
                )
            else:
                self.fields["temperature"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "temperature"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["temperature"])
        except Exception:
            self.fields["temperature"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["temperature"])

        # Air Pressure
        try:
            if imagingEnv.airPressure is not None:
                self.fields["airPressure"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "airPressure"
                            ),
                        }
                    ),
                    initial=imagingEnv.airPressure.getValue(),
                    label=("Air Pressure (%s)" % imagingEnv.airPressure.getSymbol()),
                    required=False,
                )
            else:
                self.fields["airPressure"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "airPressure"
                            ),
                        }
                    ),
                    label="Air Pressure",
                    required=False,
                )
            set_widget_attrs(self.fields["airPressure"])
        except Exception:
            self.fields["airPressure"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                label="Air Pressure",
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["airPressure"])

        # Humidity
        try:
            if imagingEnv.humidity is not None:
                self.fields["humidity"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "humidity"
                            ),
                        }
                    ),
                    initial=imagingEnv.humidity,
                    required=False,
                )
            else:
                self.fields["humidity"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "humidity"
                            ),
                        }
                    ),
                    required=False,
                )
            set_widget_attrs(self.fields["humidity"])
        except Exception:
            self.fields["humidity"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                required=False,
            )
            set_widget_attrs(self.fields["humidity"])

        # CO2 percent
        try:
            if imagingEnv.co2percent is not None:
                self.fields["co2percent"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "co2percent"
                            ),
                        }
                    ),
                    initial=imagingEnv.co2percent,
                    label="CO2 (%)",
                    required=False,
                )
            else:
                self.fields["co2percent"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "co2percent"
                            ),
                        }
                    ),
                    label="CO2 (%)",
                    required=False,
                )
            set_widget_attrs(self.fields["co2percent"])
        except Exception:
            self.fields["co2percent"] = forms.CharField(
                max_length=10,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="CO2 (%)",
                required=False,
            )
            set_widget_attrs(self.fields["co2percent"])

        self.fields.keyOrder = ["airPressure", "co2percent", "humidity", "temperature"]


class MetadataStageLabelForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MetadataStageLabelForm, self).__init__(*args, **kwargs)

        # Stage label

        # Position x
        try:
            if kwargs["initial"]["image"].getStageLabel() is not None:
                self.fields["positionx"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "positionx"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["image"].getStageLabel().positionx,
                    label="Position X",
                    required=False,
                )
            else:
                self.fields["positionx"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "positionx"
                            ),
                        }
                    ),
                    label="Position X",
                    required=False,
                )
            set_widget_attrs(self.fields["positionx"])
        except Exception:
            self.fields["positionx"] = forms.CharField(
                max_length=100,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Position X",
                required=False,
            )
            set_widget_attrs(self.fields["positionx"])

        # Position y
        try:
            if kwargs["initial"]["image"].getStageLabel() is not None:
                self.fields["positiony"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "positiony"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["image"].getStageLabel().positiony,
                    label="Position Y",
                    required=False,
                )
            else:
                self.fields["positiony"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "positiony"
                            ),
                        }
                    ),
                    label="Position Y",
                    required=False,
                )
            set_widget_attrs(self.fields["positiony"])
        except Exception:
            self.fields["positiony"] = forms.CharField(
                max_length=100,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Position Y",
                required=False,
            )
            set_widget_attrs(self.fields["positionx"])

        # Position z
        try:
            if kwargs["initial"]["image"].getStageLabel() is not None:
                self.fields["positionz"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "positionz"
                            ),
                        }
                    ),
                    initial=kwargs["initial"]["image"].getStageLabel().positionz,
                    label="Position Z",
                    required=False,
                )
            else:
                self.fields["positionz"] = forms.CharField(
                    max_length=100,
                    widget=forms.TextInput(
                        attrs={
                            "size": 25,
                            "onchange": save_metadata(
                                kwargs["initial"]["image"].id, "positionz"
                            ),
                        }
                    ),
                    label="Position Z",
                    required=False,
                )
            set_widget_attrs(self.fields["positionz"])
        except Exception:
            self.fields["positionz"] = forms.CharField(
                max_length=100,
                widget=forms.TextInput(attrs={"size": 25}),
                initial="N/A",
                label="Position Z",
                required=False,
            )
            set_widget_attrs(self.fields["positionz"])

        self.fields.keyOrder = ["positionx", "positiony", "positionz"]
