public int copyModel(int PD_ProcessId)
        {
            var process = _pdesignerDB.PD_Processes.Find(PD_ProcessId);

            PD_Process newProcess = new PD_Process() { Name = process.Name };

            _pdesignerDB.PD_Processes.Add(newProcess);
            _pdesignerDB.SaveChanges();

            foreach(var p in process.Parameters)
            {
                PD_Parameter par = new PD_Parameter() { PD_Process_Id = newProcess.Id, Name = p.Name, Config = p.Config };
                _pdesignerDB.PD_Parameters.Add(par);
                _pdesignerDB.SaveChanges();
            }

            foreach(var mt in process.MessageTypes)
            {
                PD_MessageType newMessageType = new PD_MessageType() { Id = mt.Id, Name = mt.Name, Parameters = mt.Parameters, PD_Process_Id = newProcess.Id };
                _pdesignerDB.PD_MessageTypes.Add(newMessageType);
                _pdesignerDB.SaveChanges();
            }

            foreach(var m in process.Messages)
            {
                PD_Message newMessage = new PD_Message() { Id = m.Id, From = m.From, To = m.To, PD_MessageType_Id = m.PD_MessageType_Id, PD_MessageType_Process_Id = newProcess.Id, PD_Process_Id = newProcess.Id };
                _pdesignerDB.PD_Messages.Add(newMessage);
                _pdesignerDB.SaveChanges();
            }

            foreach (var s in process.Subjects)
            {
                PD_Subject newSubject = new PD_Subject() { Id = s.Id, CanBeStarted = s.CanBeStarted, ExternalSubject = s.ExternalSubject, GlobalParameters = s.GlobalParameters, MultiSubject = s.MultiSubject, Name = s.Name, PD_Process_Id = newProcess.Id, PositionLeft = s.PositionLeft, PositionTop = s.PositionTop };
                _pdesignerDB.PD_Subjects.Add(newSubject);
                _pdesignerDB.SaveChanges();

                foreach (var st in s.States)
                {
                    if (st.Type == PD_StateTypes.FunctionState)
                    {
                        var oS = (PD_FunctionState)st;
                        PD_FunctionState newS = new PD_FunctionState() { EditableParameters = oS.EditableParameters, EndState = oS.EndState, Id = oS.Id, Name = oS.Name, PD_Process_Id = newProcess.Id, PD_Subject_Id = newSubject.Id, PositionLeft = oS.PositionLeft, PositionTop = oS.PositionTop, ReadableParameters = oS.ReadableParameters, StartState = oS.StartState, Type = oS.Type };
                        _pdesignerDB.PD_FunctionStates.Add(newS);
                        _pdesignerDB.SaveChanges();
                    }
                    if (st.Type == PD_StateTypes.SendState)
                    {
                        var oS = (PD_SendState)st;
                        PD_SendState newS = new PD_SendState() { EditableParameters = oS.EditableParameters, EndState = oS.EndState, Id = oS.Id, Name = oS.Name, PD_Process_Id = newProcess.Id, PD_Subject_Id = newSubject.Id, PositionLeft = oS.PositionLeft, PositionTop = oS.PositionTop, ReadableParameters = oS.ReadableParameters, StartState = oS.StartState, Type = oS.Type, Message = oS.Message };
                        _pdesignerDB.PD_SendStates.Add(newS);
                        _pdesignerDB.SaveChanges();
                    }
                    if (st.Type == PD_StateTypes.ReceiveState)
                    {
                        var oS = (PD_ReceiveState)st;
                        PD_ReceiveState newS = new PD_ReceiveState() { EndState = oS.EndState, Id = oS.Id, Name = oS.Name, PD_Process_Id = newProcess.Id, PD_Subject_Id = newSubject.Id, PositionLeft = oS.PositionLeft, PositionTop = oS.PositionTop, StartState = oS.StartState, Type = oS.Type };
                        _pdesignerDB.PD_ReceiveStates.Add(newS);
                        _pdesignerDB.SaveChanges();
                    }
                }

                foreach (var t in s.Transitions)
                {
                    if (t.Type == PD_TransitionTypes.RegularTransition)
                    {
                        var oT = (PD_RegularTransition)t;
                        PD_RegularTransition newT = new PD_RegularTransition() { Id = oT.Id, Name = oT.Name, PD_Process_Id = newProcess.Id, PD_Subject_Id = newSubject.Id, Source = oT.Source, Target = oT.Target, Type = oT.Type };
                        _pdesignerDB.PD_RegularTransitions.Add(newT);
                        _pdesignerDB.SaveChanges();
                    }
                    if (t.Type == PD_TransitionTypes.ReceiveTransition)
                    {
                        var oT = (PD_ReceiveTransition)t;
                        PD_ReceiveTransition newT = new PD_ReceiveTransition() { Id = oT.Id, PD_Process_Id = newProcess.Id, PD_Subject_Id = newSubject.Id, Source = oT.Source, Target = oT.Target, Type = oT.Type, Message = oT.Message };
                        _pdesignerDB.PD_ReceiveTransitions.Add(newT);
                        _pdesignerDB.SaveChanges();
                    }
                    if (t.Type == PD_TransitionTypes.TimeoutTransition)
                    {
                        var oT = (PD_TimeoutTransition)t;
                        PD_TimeoutTransition newT = new PD_TimeoutTransition() { Id = oT.Id, PD_Process_Id = newProcess.Id, PD_Subject_Id = newSubject.Id, Source = oT.Source, Target = oT.Target, Type = oT.Type, TimeSpan = oT.TimeSpan };
                        _pdesignerDB.PD_TimeoutTransitions.Add(newT);

                    }
                }
            }

            _pdesignerDB.SaveChanges();

            return newProcess.Id;
        }
         public ActionResult _EditParameter(int processid, int subjectid, string parameter, int edit)
         {
             PD_Parameter_ViewModel pvm;
             PD_Parameter pc = new PD_Parameter() { PD_Process_Id = processid };
             if (parameter != null)
             {
                 pc = _db.PD_Parameters.Find(processid, parameter);

                 var cfg = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(pc.Config);
                 //_DeleteParameter(processid, subjectid, parameter);
                  //_EditMessageParameter(int processid, int messagetypeId, string parameter, int edit, string messageName)
                 //_db.PD_Parameters.Add(pc);


                 pvm = new PD_Parameter_ViewModel() { Name = pc.Name, Type = cfg.Type, DefaultValue = cfg.Value.ToString(), Process_Id = processid, Subject_Id = subjectid };
             }
             else
             {
                 pvm = new PD_Parameter_ViewModel() { Process_Id = processid, Subject_Id = subjectid, Type = "string" , DefaultValue = "0" };
             }
             ViewBag.Edit = edit;
             return PartialView(pvm);
         }
        public ActionResult _EditLoadImportedSubject(int processidNew, int subjId, int processidOld, int edit)
        {

            var _p = _db.PD_Processes.Find(processidOld);
            PD_Subject subject = _db.PD_Subjects.Find(processidNew, subjId);
            Random rand = new Random();
            PD_Subject newSubject = new PD_Subject() { Name = subject.Name, PositionTop = rand.Next(0, 800), PositionLeft = rand.Next(0, 555), ExternalSubject = false, CanvasWidth = subject.CanvasWidth, CanvasHeight = subject.CanvasHeight };
            newSubject.Id = IdHelper.getSubjectId(_db, processidOld);
            _p.Subjects.Add(newSubject);
            _db.SaveChanges();
            

            //messages
            var messages = _db.PD_Messages.Where(result => result.PD_Process_Id == processidNew && result.From == subject.Id || result.PD_Process_Id == processidNew && result.To == subject.Id).ToList();
            List<int> messageIds = new List<int>();
            foreach (var x in messages) { messageIds.Add((int)x.PD_MessageType_Id); }
            messageIds = messageIds.Distinct().ToList();
            foreach (var y in messageIds)
            {
               var newMes = new PD_MessageType() { PD_Process_Id = processidOld };
               newMes.Id = IdHelper.getMessageTypeId(_db, processidOld);
               newMes.Name = _db.PD_MessageTypes.Find(processidNew, y).Name;
               newMes.Parameters = _db.PD_MessageTypes.Find(processidNew, y).Parameters;
               var Names= _db.PD_MessageTypes.Where(result => result.PD_Process_Id == processidOld && result.Name == newMes.Name);
               if (Names.Count() == 0)
               {
                   _db.PD_MessageTypes.Add(newMes);
                   foreach (var z in _db.PD_MessageTypes.Find(processidNew, y).Parameters) //parameters
                   {
                       var param = _db.PD_Parameters.Find(processidNew, z);
                       var checkParamName = _db.PD_Parameters.Find(processidOld, param.Name);
                       //var paramNames = _db.PD_Parameters.Where(result => result.PD_Process_Id == processidNew && result.Name == param.Name);
                       if (checkParamName == null)
                       {
                           PD_Parameter paramNew = new PD_Parameter() { PD_Process_Id = processidOld };
                           paramNew.Name = param.Name;
                           paramNew.Config = param.Config;
                           _db.PD_Parameters.Add(paramNew);
                       }
                   }
               }
               _db.SaveChanges();
            }
            

            //state && transitions            
            var states = _db.PD_States.Where(result => result.PD_Process_Id == processidNew && result.PD_Subject_Id == subject.Id).ToList();
            var i = 1;
            foreach (var x in states)
            {
                PD_State newState = null;
                
                if (x.Type == PD_StateTypes.FunctionState) 
                {
                    newState = new PD_FunctionState() { Name = "Function State", EndState = false };
                }
                if (x.Type == PD_StateTypes.SendState)
                {
                    newState = new PD_SendState() { Name = "Send State", EndState = false };
                    //((PD_SendState)newState).ReadableParameters = ((PD_SendState)x).ReadableParameters;
                    //((PD_SendState)newState).EditableParameters = ((PD_SendState)x).EditableParameters;
                }
                if (x.Type == PD_StateTypes.ReceiveState)
                {
                    newState = new PD_ReceiveState() { Name = "Receive State", EndState = false };
                } 
                //newState.PD_Subject = x.PD_Subject;
                //newState.PD_Subject_Id = newSubject.Id;
                //newState.Id = IdHelper.getStateId(_db, processidOld, subjId);
                //newState.Id = IdHelper.getStateId(_db, _p.Id, newSubject.Id);
                //newState.PD_Process_Id = processidOld;
                //newState.Id = i;
                newState.Id = x.Id;
                i++;
                
                newState.Name = x.Name;
                newState.PositionLeft = x.PositionLeft;
                newState.PositionTop = x.PositionTop;
                newState.StartState = x.StartState;
                newState.EndState = x.EndState;
                newSubject.States.Add(newState);            
            }
            _db.SaveChanges();

            i = 1;
            var transitions = _db.PD_Transitions.Where(result => result.PD_Process_Id == processidNew && result.PD_Subject_Id == subject.Id).ToList();
            foreach (var x in transitions)
            {
                 PD_Transition newTransition = null;

                 var temp = new PD_TransitionDTO() { Id = x.Id, Source = x.Source, Target = x.Target, Type = x.Type, LabelPosition = x.LabelPosition };
                 
                 if (x.Type == PD_TransitionTypes.RegularTransition)
                 {
                     temp.Label = ((PD_RegularTransition)x).Name;
                     newTransition = new PD_RegularTransition() { Name = temp.Label };                     
                 }
                 if (x.Type == PD_TransitionTypes.ReceiveTransition)
                 {
                      newTransition = new PD_ReceiveTransition() { Message = -1 };
                 }
                 if (x.Type == PD_TransitionTypes.TimeoutTransition)
                 {
                     temp.Label = ((PD_TimeoutTransition)x).TimeSpan;
                     newTransition = new PD_TimeoutTransition() { TimeSpan = temp.Label };
                 }

                 //newTransition.Id = IdHelper.getTransitionId(_db, processidOld, subjId);
                 //newTransition.Id = i;
                 newTransition.Id = x.Id;
                 i++;
                 newTransition.PD_Process_Id = processidOld;
                 newTransition.Source = x.Source;
                 newTransition.Target = x.Target;
                 newTransition.LabelPosition = x.LabelPosition;
                 newSubject.Transitions.Add(newTransition);
            }
            _db.SaveChanges();
            
            string a = "location.reload();";
            string b = "imprt('" + subject.Name + "','" + newSubject.Id + "','" + newSubject.PositionLeft + "','" + newSubject.PositionTop + "','" + processidOld + "')";
            return JavaScript(b);
            //return null;
        }
        public ActionResult _EditMessageParameterNoSubmit(int processid, string name, string previousName, int messageTypeId, string defaultv, string type, string messageName, bool ft)
        {
            
            if(type=="bobasic")defaultv = "{\"bo\": " + defaultv + ",  \"boi\": -1}";
            var _p = _db.PD_Processes.Find(processid);
            if (User.Identity.Name.Equals(_p.LockedBy))
            {
                PD_Parameter p = _db.PD_Parameters.Find(processid, name);
                if (p == null)//it didn't exist before
                {
                    if (previousName != null)//it had previous name, meaning the name was changed from a previous name
                    {
                        _DeleteMessageParameter(processid, messageTypeId, previousName); 
                    }
                    string val = defaultv;
                    if (type.Equals("string"))
                    {
                        val = "\"" + val + "\"";
                    }
                    string cfg = "{\"Type\":\"" + type + "\",\"Value\":" + val + "}";
                    p = new PD_Parameter() { PD_Process_Id = processid, Name = name, Config = cfg };
                    _db.PD_Parameters.Add(p);
                }
                else //it did exist already
                {
                    //List<PD_MessageType> mylist2 = _db.PD_MessageTypes.Where(x => x.PD_Process_Id == processid && x.Parameters.ToList().Contains(previousName)).ToList<PD_MessageType>();                    
                    
                    List<PD_MessageType> mylist2 = _db.PD_MessageTypes.Where(x => x.PD_Process_Id == processid && x.Id != messageTypeId).ToList<PD_MessageType>();                    
                    foreach (var i in mylist2)//check if exists in some other messageTypeId first
                    {
                        if (i.Parameters.Contains(name) && ft) return JavaScript("$('#changeRepeated').modal('show');");
                    } 

                    try
                    {
                        defaultv = checkDefaultValue(type, defaultv);
                    }
                    catch (Exception e)
                    {
                        return RedirectToAction("ViewProcess", new { processid = processid, edit = 1 });
                    }
                    string val = defaultv;
                    if (type.Equals("string"))
                    {
                        val = "\"" + val + "\"";
                    }
                    p.Config = "{\"Type\":\"" + type + "\",\"Value\":" + val + "}";
                }
                var item = _db.PD_MessageTypes.Find(processid, messageTypeId);
                if (item == null)
                {
                    item = new PD_MessageType() { PD_Process_Id = processid };
                    item.Name = messageName;
                    item.Id = IdHelper.getMessageTypeId(_db, processid);
                    _db.PD_MessageTypes.Add(item);
                }
                if (!item.Parameters.Contains(name))
                {
                    item.Parameters.Add(name);
                }

                List<PD_Subject> mylist = _db.PD_Subjects.Where(x => x.PD_Process_Id == processid).ToList<PD_Subject>();
                foreach (var i in mylist)
                {
                    i.GlobalParameters.Remove(previousName);
                    if (name != null) i.GlobalParameters.Add(name);
                }
                _db.SaveChanges();
                return RedirectToAction("_EditMessageType", new { processid = processid, id = item.Id, edit = 1 });  
            }
            else
            {
                return null;
            }
        }
        public ActionResult _EditMessageParameter(PD_MessageParameter_ViewModel model)
        {
            var _p = _db.PD_Processes.Find(model.Process_Id);
            if (User.Identity.Name.Equals(_p.LockedBy))
            //_p.MessageTypes[].Parameter.Results View
            {
                PD_Parameter p = _db.PD_Parameters.Find(model.Process_Id, model.Name);
                if (p == null)     
                {
                    if (model.previousName != null)
                    {
                        _DeleteMessageParameter(model.Process_Id, model.Message_Type_Id, model.previousName);
                    }
                    string val = model.DefaultValue;
                    if (model.Type.Equals("string"))
                    {
                        val = "\"" + val + "\"";
                    }
                    string cfg = "{\"Type\":\"" + model.Type + "\",\"Value\":" + val + "}";
                    p = new PD_Parameter() { PD_Process_Id = model.Process_Id, Name = model.Name, Config = cfg };
                    _db.PD_Parameters.Add(p);

                }else          
                {                         
                    try
                    {
                       model.DefaultValue = checkDefaultValue(model.Type, model.DefaultValue);
                    }catch(Exception e)
                    {
                        return RedirectToAction("ViewProcess", new { processid = model.Process_Id, edit = 1 });
                    }
                    string val = model.DefaultValue;
                    if (model.Type.Equals("string"))
                    {
                        val = "\"" + val + "\"";
                    }
                    p.Config = "{\"Type\":\"" + model.Type + "\",\"Value\":" + val + "}";
                }
                var item = _db.PD_MessageTypes.Find(model.Process_Id, model.Message_Type_Id);
                if (item == null)
                {
                    item = new PD_MessageType() { PD_Process_Id = model.Process_Id };
                    item.Name = model.messageName;                    
                    item.Id = IdHelper.getMessageTypeId(_db, model.Process_Id);
                    _db.PD_MessageTypes.Add(item);
                }
                if (!item.Parameters.Contains(model.Name))
                {
                    item.Parameters.Add(model.Name);
                }


                List<PD_Subject> mylist = _db.PD_Subjects.Where(x => x.PD_Process_Id == model.Process_Id).ToList<PD_Subject>();
                foreach (var i in mylist)
                {
                    //i.GlobalParameters.SerializedValue.Replace(parameter,"");
                    i.GlobalParameters.Remove(model.previousName);
                    if(model.Name!=null)i.GlobalParameters.Add(model.Name);
                }
                _db.SaveChanges();
                //need via AJAX or rewrite this all
                return RedirectToAction("ViewProcess", new { processid = model.Process_Id, edit = 1 });    //original, working

                //return View(model);
                //return RedirectToAction("_EditMessageType", new { processid = model.Process_Id, id = item.Id, edit = 1 });      //first way, not working, 
                
                //var model2 = new PD_MessageTypeDTO_ViewModel() { Id = model.Process_Id, PD_Process_Id = item.Id, Name = item.Name, Parameters = new List<PD_Parameter_ViewModel>() }; //second way, not working
                //model2.Parameters = listofStringParametersToViewModel(model.Process_Id, item.Parameters);
                //return View(_EditMessageType(model.Process_Id,item.Id,1));

                //var model2  = new PD_MessageParameter_ViewModel() { Name = pc.Name, Type = cfg.Type, DefaultValue = cfg.Value.ToString(), Process_Id = processid, Message_Type_Id = messagetypeId, previousName = parameter, messageName = messageName };
                //var model2 = new PD_MessageParameter_ViewModel() {};
                //return PartialView(model2);

                //return RedirectToAction("_EditMessageParameter", new { processid = model.Process_Id, messagetypeId = item.Id,  edit = 1 }); 

            }
            else
            {
                return null;
            }
        }
        public ActionResult _EditParameter(PD_Parameter_ViewModel model)
         {
             var _p = _db.PD_Processes.Find(model.Process_Id);
             if (User.Identity.Name.Equals(_p.LockedBy))
             {
                 PD_Parameter p = _db.PD_Parameters.Find(model.Process_Id, model.Name);
                 if (p == null)
                 {
                     string val = model.DefaultValue;
                     if (model.Type.Equals("string"))
                     {
                         val = "\"" + val + "\"";
                     }
                     string cfg = "{\"Type\":\"" + model.Type +"\",\"Value\":" + val + "}";
                     p = new PD_Parameter() { PD_Process_Id = model.Process_Id, Name = model.Name, Config = cfg };
                     _db.PD_Parameters.Add(p);
                 }
                 else
                 {
                     try
                     {
                         model.DefaultValue = checkDefaultValue(model.Type, model.DefaultValue);
                     }
                     catch (Exception e)
                     {
                         return RedirectToAction("ViewSubject", new { processid = model.Process_Id, subjectid = model.Subject_Id, edit = 1 });
                     }
                     string val = model.DefaultValue;
                     if (model.Type.Equals("string"))
                     {
                         val = "\"" + val + "\"";
                     }
                     p.Config = "{\"Type\":\"" + model.Type + "\",\"Value\":" + val + "}";
                 }
                 var item = _db.PD_Subjects.Find(model.Process_Id, model.Subject_Id);

                 if (!item.GlobalParameters.Contains(model.Name))
                 {
                     item.GlobalParameters.Add(model.Name);
                 }
                 _db.SaveChanges();

                 return RedirectToAction("ViewSubject", new { processid = model.Process_Id, subjectid = model.Subject_Id, edit = 1 });
             }
             else
             {
                 return null;
             }
         }