private void ViewToModelObjsSimples(List <ObjDigSimples> odsSimples, ObjDigComposto odComp, GISADataset.ObjetoDigitalRow odRowComp)
        {
            odsSimples.ForEach(odSimples =>
            {
                var odRow = default(GISADataset.ObjetoDigitalRow);
                switch (odSimples.state)
                {
                case State.added:
                    if (odComp != null && odComp.state != State.deleted)
                    {
                        CreateDatabaseObjDigSimples(odComp, odRowComp, odSimples);
                    }
                    else
                    {
                        CreateDatabaseObjDigSimplesSolto(odSimples);
                    }
                    break;

                case State.modified:
                    odRow           = GisaDataSetHelper.GetInstance().ObjetoDigital.Cast <GISADataset.ObjetoDigitalRow>().Single(r => r.RowState != DataRowState.Deleted && r.pid.Equals(odSimples.pid));
                    odRow.Titulo    = odSimples.titulo;
                    odRow.Publicado = odSimples.publicado;
                    odRow.GUIOrder  = odSimples.guiorder;

                    UpdateNvlDocSimplesOrderNr(odSimples);

                    if (odComp != null)
                    {
                        AddOrRemoveODRelations(odComp, odSimples, odRow);
                    }
                    break;

                case State.deleted:
                    odRow = GisaDataSetHelper.GetInstance().ObjetoDigital.Cast <GISADataset.ObjetoDigitalRow>().Single(r => r.RowState != DataRowState.Deleted && r.pid.Equals(odSimples.pid));
                    FedoraHelper.DeleteObjDigitalRows(odRow);
                    break;

                case State.unchanged:     // apanhar o caso de a ordem do OD Simples ter mudado
                    odRow          = GisaDataSetHelper.GetInstance().ObjetoDigital.Cast <GISADataset.ObjetoDigitalRow>().Single(r => r.RowState != DataRowState.Deleted && r.pid.Equals(odSimples.pid));
                    odRow.GUIOrder = odSimples.guiorder;

                    UpdateNvlDocSimplesOrderNr(odSimples);

                    if (odComp != null)
                    {
                        AddOrRemoveODRelations(odComp, odSimples, odRow);
                    }
                    break;
                }
            });

            // atualizar a tipologia e assuntos dos objetos simples
            // - se houver um objeto composto, nenhum dos seus simples não pode ter tipologia e assuntos definidos
            // - se não houver um objeto composto:
            //   * se o nro de objetos simples for um, então esse objeto simples pode ter tipologia e assuntos definidos
            //   * se o nro de objetos simples for maior que um, então nenhum desses objetos pode ter tipologia e assuntos definidos
            if (odComp == null || odComp.state == State.deleted)
            {
                var ods = odsSimples.Where(od => od.state != State.deleted);
                if (ods.Count() == 1)
                {
                    var odSimples = ods.Single();
                    var frdRow    = currentNivel.GetFRDBaseRows().Single();
                    var idxTip    = frdRow.GetIndexFRDCARows().SingleOrDefault(idx => idx["Selector"] != DBNull.Value && idx.Selector == -1);
                    if (idxTip != null)
                    {
                        odSimples.tipologia = idxTip.ControloAutRow.GetControloAutDicionarioRows().Single(cad => cad.IDTipoControloAutForma == (long)TipoControloAutForma.FormaAutorizada).DicionarioRow.Termo;
                    }

                    var assuntos = frdRow.GetIndexFRDCARows().Where(idx => idx.ControloAutRow.IDTipoNoticiaAut < 4).SelectMany(idx => idx.ControloAutRow.GetControloAutDicionarioRows()).Where(cad => cad.IDTipoControloAutForma == (long)TipoControloAutForma.FormaAutorizada).Select(cad => cad.DicionarioRow.Termo);
                    if (assuntos.Count() > 0)
                    {
                        odSimples.assuntos = assuntos.ToList();
                    }
                }
                else
                {
                    odsSimples.Where(od => od.state != State.deleted).ToList().ForEach(od =>
                    {
                        od.tipologia = "";
                        od.assuntos.Clear();
                        if (od.state == State.unchanged)
                        {
                            od.state = State.modified;
                        }
                    });
                }
            }
            else
            {
                odsSimples.Where(od => od.state != State.deleted).ToList().ForEach(od =>
                {
                    od.tipologia = "";
                    od.assuntos.Clear();
                    if (od.state == State.unchanged)
                    {
                        od.state = State.modified;
                    }
                });
            }
        }
        public void ViewToModel(Contexto viewMode, bool disableSave)
        {
            var tnrID = currentNivel.GetRelacaoHierarquicaRowsByNivelRelacaoHierarquica().First().IDTipoNivelRelacionado;

            if (viewMode == ObjetoDigitalFedoraHelper.Contexto.imagens)
            {
                // neste modo, o contexto é sempre um subdocumento e como tal tem que se ter em consideração informação sobre o subdocumento e o seu documento/processo
                Trace.Assert(tnrID == (long)TipoNivelRelacionado.SD);

                var repoName  = SessionHelper.AppConfiguration.GetCurrentAppconfiguration().FedoraHelperSingleton.GetRepositoryName();
                var imgVolRow = FedoraHelper.GetRepositoryImagemVolumeRow();

                Debug.Assert(currentODSimples.Count <= 1); // no contexto de um subdocumento só pode haver 1 OD no máximo
                if (currentODSimples.Count == 1)
                {
                    var odSimples = currentODSimples[0];
                    if (odSimples.state == State.added)
                    {
                        var frdRow = currentNivel.GetFRDBaseRows().Single();
                        odSimples.gisa_id = FedoraHelper.gisaPrefix + currentNivel.ID;

                        var idxTip = frdRow.GetIndexFRDCARows().SingleOrDefault(idx => idx["Selector"] != DBNull.Value && idx.Selector == -1);
                        if (idxTip != null)
                        {
                            odSimples.tipologia = idxTip.ControloAutRow.GetControloAutDicionarioRows().Single(cad => cad.IDTipoControloAutForma == (long)TipoControloAutForma.FormaAutorizada).DicionarioRow.Termo;
                        }

                        var assuntos = frdRow.GetIndexFRDCARows().Where(idx => idx.ControloAutRow.IDTipoNoticiaAut < 4).SelectMany(idx => idx.ControloAutRow.GetControloAutDicionarioRows()).Where(cad => cad.IDTipoControloAutForma == (long)TipoControloAutForma.FormaAutorizada).Select(cad => cad.DicionarioRow.Termo);
                        if (assuntos.Count() > 0)
                        {
                            odSimples.assuntos = assuntos.ToList();
                        }

                        var imgRow = GisaDataSetHelper.GetInstance().SFRDImagem.NewSFRDImagemRow();
                        imgRow.Identificador       = "";
                        imgRow.FRDBaseRow          = frdRow;
                        imgRow.Tipo                = FedoraHelper.typeFedora;
                        imgRow.Versao              = new byte[] { };
                        imgRow.isDeleted           = 0;
                        imgRow.GUIOrder            = long.MaxValue;
                        imgRow.Descricao           = "";
                        imgRow.SFRDImagemVolumeRow = imgVolRow;
                        GisaDataSetHelper.GetInstance().SFRDImagem.AddSFRDImagemRow(imgRow);

                        if (currentODComp != null)
                        {
                            Debug.Assert(currentObjetoDigitalRowComp != null);

                            var nUpperRow = currentNivel.GetRelacaoHierarquicaRowsByNivelRelacaoHierarquica().Single().NivelRowByNivelRelacaoHierarquicaUpper;
                            odSimples.parentDocumentTitle = nUpperRow.GetNivelDesignadoRows().Single().Designacao;
                            var orderNr = currentNivel.GetNivelDesignadoRows().Single().GetNivelDocumentoSimplesRows().Single().GUIOrder;
                            odSimples.guiorder      = orderNr;
                            currentObjetoDigitalRow = GisaDataSetHelper.GetInstance().ObjetoDigital.AddObjetoDigitalRow(odSimples.pid, odSimples.titulo, odSimples.publicado, orderNr, new byte[] { }, 0);
                            GisaDataSetHelper.GetInstance().ObjetoDigitalRelacaoHierarquica.AddObjetoDigitalRelacaoHierarquicaRow(currentObjetoDigitalRow, currentObjetoDigitalRowComp, new byte[] { }, 0);

                            currentODComp.objSimples.Insert((int)odSimples.guiorder - 1, odSimples);
                        }
                        else
                        {
                            var ndsRow = currentNivel.GetNivelDesignadoRows().Single().GetNivelDocumentoSimplesRows().Single();
                            currentObjetoDigitalRow = GisaDataSetHelper.GetInstance().ObjetoDigital.AddObjetoDigitalRow(odSimples.pid, odSimples.titulo, odSimples.publicado, ndsRow.GUIOrder, new byte[] { }, 0);
                        }

                        GisaDataSetHelper.GetInstance().SFRDImagemObjetoDigital.AddSFRDImagemObjetoDigitalRow(imgRow.IDFRDBase, imgRow.idx, currentObjetoDigitalRow, new byte[] { }, 0);
                        //PermissoesHelper.AddNewObjDigGrantPermissions(currentObjetoDigitalRow, currentNivel);
                        newObjects.Add(currentObjetoDigitalRow, odSimples);
                    }
                    else if (odSimples.state == State.modified)
                    {
                        currentObjetoDigitalRow.Titulo    = odSimples.titulo;
                        currentObjetoDigitalRow.Publicado = odSimples.publicado;

                        if (currentODComp != null)
                        {
                            currentObjetoDigitalRowComp.Publicado = currentODComp.publicado;
                        }
                    }
                    else if (odSimples.state == State.deleted)
                    {
                        FedoraHelper.DeleteObjDigitalRows(currentObjetoDigitalRow);
                        if (currentODComp != null && currentODComp.state == State.deleted)
                        {
                            FedoraHelper.DeleteObjDigitalRows(currentObjetoDigitalRowComp);
                        }
                    }
                }
            }
            else if (mContexto == ObjetoDigitalFedoraHelper.Contexto.objetosDigitais)
            {
                if (disableSave)
                {
                    return;
                }

                if (currentODComp != null) // caso onde existe um OD composto associado à UI
                {
                    var odRowComp = default(GISADataset.ObjetoDigitalRow);
                    switch (currentODComp.state)
                    {
                    case State.added:
                        currentODComp.gisa_id = FedoraHelper.gisaPrefix + currentNivel.ID;
                        var frdRow    = currentNivel.GetFRDBaseRows().Single();
                        var imgVolRow = FedoraHelper.GetRepositoryImagemVolumeRow();
                        var imgRow    = GisaDataSetHelper.GetInstance().SFRDImagem.NewSFRDImagemRow();
                        imgRow.Identificador       = "";
                        imgRow.FRDBaseRow          = frdRow;
                        imgRow.Tipo                = FedoraHelper.typeFedora;
                        imgRow.Versao              = new byte[] { };
                        imgRow.isDeleted           = 0;
                        imgRow.GUIOrder            = long.MaxValue;
                        imgRow.Descricao           = "";
                        imgRow.SFRDImagemVolumeRow = imgVolRow;
                        GisaDataSetHelper.GetInstance().SFRDImagem.AddSFRDImagemRow(imgRow);

                        currentObjetoDigitalRowComp = GisaDataSetHelper.GetInstance().ObjetoDigital.AddObjetoDigitalRow(currentODComp.pid, currentODComp.titulo, currentODComp.publicado, 1, new byte[] { }, 0);
                        GisaDataSetHelper.GetInstance().SFRDImagemObjetoDigital.AddSFRDImagemObjetoDigitalRow(imgRow.IDFRDBase, imgRow.idx, currentObjetoDigitalRowComp, new byte[] { }, 0);

                        //PermissoesHelper.AddNewObjDigGrantPermissions(currentObjetoDigitalRowComp, currentNivel);

                        newObjects.Add(currentObjetoDigitalRowComp, currentODComp);

                        var idxTip = frdRow.GetIndexFRDCARows().SingleOrDefault(idx => idx["Selector"] != DBNull.Value && idx.Selector == -1);
                        if (idxTip != null)
                        {
                            currentODComp.tipologia = idxTip.ControloAutRow.GetControloAutDicionarioRows().Single(cad => cad.IDTipoControloAutForma == (long)TipoControloAutForma.FormaAutorizada).DicionarioRow.Termo;
                        }

                        var assuntos = frdRow.GetIndexFRDCARows().Where(idx => idx.ControloAutRow.IDTipoNoticiaAut < 4).SelectMany(idx => idx.ControloAutRow.GetControloAutDicionarioRows()).Where(cad => cad.IDTipoControloAutForma == (long)TipoControloAutForma.FormaAutorizada).Select(cad => cad.DicionarioRow.Termo);
                        if (assuntos.Count() > 0)
                        {
                            currentODComp.assuntos = assuntos.ToList();
                        }

                        break;

                    case State.modified:
                        currentObjetoDigitalRowComp.Titulo    = currentODComp.titulo;
                        currentObjetoDigitalRowComp.Publicado = currentODComp.publicado;
                        break;

                    case State.deleted:
                        FedoraHelper.DeleteObjDigitalRows(currentObjetoDigitalRowComp);
                        break;
                    }

                    odRowComp = currentObjetoDigitalRowComp;

                    ViewToModelObjsSimples(currentODComp.objSimples, currentODComp, odRowComp);
                }
                else // caso onde só existem ODs simples soltos associados à UI
                {
                    ViewToModelObjsSimples(currentODSimples);
                }
            }


            // atribuir permissões aos objectos digitais novos
            var odRows = GisaDataSetHelper.GetInstance().ObjetoDigital.Cast <GISADataset.ObjetoDigitalRow>().Where(r => r.RowState == DataRowState.Added).ToList();

            PermissoesHelper.AddNewObjDigGrantPermissions(odRows, currentNivel);

            // atribuir permissão de leitura ao grupo publicados consoante o valor da flag publicado definida nas datarows GISADataset.ObjetoDigitalRow que foram adicionadas ou editadas
            GisaDataSetHelper.GetInstance().ObjetoDigital.Cast <GISADataset.ObjetoDigitalRow>().Where(r => r.RowState == DataRowState.Added || r.RowState == DataRowState.Modified).ToList()
            .ForEach(odRow => PermissoesHelper.ChangeObjDigPermissionPublicados(odRow));

            // actualizar ordem dos subdocumentos sem objeto digital
            docSimplesSemOD.ForEach(docSimples => docSimples.nRow.GetNivelDesignadoRows().Single().GetNivelDocumentoSimplesRows().Single().GUIOrder = docSimples.guiorder);
        }