// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
(function(cloudStack) {
  cloudStack.sections.events = {
    title: 'label.menu.events',
    id: 'events',
    sectionSelect: {
      preFilter: function(args) {
        if(isAdmin())
          return ["events", "alerts"];
        else
          return ["events"];
      },
      label: 'label.select-view'
    },
    sections: {
      events: {
        type: 'select',
        title: 'label.menu.events',
        listView: {
          id: 'events',
          label: 'label.menu.events',
          fields: {            
            description: { label: 'label.description' },
	    level: { label: 'label.level' },
            type: {label:'Type'},
            domain: { label: 'label.domain' },
	    account: { label: 'label.account' },
            created: { label: 'label.date', converter: cloudStack.converters.toLocalDate }
          },

          actions: {
            // Remove multiple events
            remove: {
              label: 'Delete Events',
              isHeader: true,
              addRow: false,
              messages: {
                notification: function(args) {
                  return 'Events Deleted';
                }
              },
              createForm: {
                title:'Delete Events',
                desc: '',
                fields: {
                  type: { label: 'By event type'  , docID:'helpEventsDeleteType'},
                  date: {
                    label: 'By date (older than)',
                    docID:'helpEventsDeleteDate',
                    isDatepicker: true
                  }
                }
              },
             action: function(args) {

                var data={};

                if(args.data.type != "")
                  $.extend(data, { type:args.data.type });

                if(args.data.date != "")
                  $.extend(data, {olderthan:args.data.date });
   
                $.ajax({

                     url:createURL("deleteEvents"),
                     data:data,
                     dataType:'json',
                     async: false,

                  success:function(data){

                  args.response.success();
               
                    }  
                   });
                                  // Reloads window with events removed
                $(window).trigger('cloudStack.fullRefresh');
              }
            },

            // Archive multiple events
            archive: {
              label: 'Archive Events',
              isHeader: true,
              addRow: false,
              messages: {
                notification: function(args) {
                  return 'Archive events';
                }
              },
              createForm: {
                title:'Archive Events',
                desc: '',
                fields: {
                  type: { label: 'By event type' , docID:'helpEventsArchiveType'},
                  date: { label: 'By date (older than)' , docID:'helpEventsArchiveDate', isDatepicker: true },
                }
              },
              action: function(args) {
                   var data={};

                if(args.data.type != "")
                  $.extend(data, { type:args.data.type });

                if(args.data.date != "")
                  $.extend(data, {olderthan:args.data.date });

                $.ajax({

                     url:createURL("archiveEvents"),
                     data:data,
                     dataType:'json',
                     async: false,

                  success:function(data){

                  args.response.success();

                    }
                   });

                // Reloads window with events removed
                $(window).trigger('cloudStack.fullRefresh');
              }
            }

          },


										
					advSearchFields: {	
            level: {
						  label: 'label.level',
							select: function(args) {
							  args.response.success({
									data: [
									  {id: '', description: ''}, 
									  {id: 'INFO', description: 'INFO'}, 
										{id: 'WARN', description: 'WARN'}, 
										{id: 'ERROR', description: 'ERROR'}
									]
								});
							}
						},					
						
						domainid: {					
							label: 'Domain',					
							select: function(args) {
								if(isAdmin() || isDomainAdmin()) {
									$.ajax({
										url: createURL('listDomains'),
										data: { 
											listAll: true,
											details: 'min'
										},
										success: function(json) {
											var array1 = [{id: '', description: ''}];
											var domains = json.listdomainsresponse.domain;
											if(domains != null && domains.length > 0) {
												for(var i = 0; i < domains.length; i++) {
													array1.push({id: domains[i].id, description: domains[i].path});
												}
											}
											args.response.success({
												data: array1
											});
										}
									});
								}
								else {
									args.response.success({
										data: null
									});
								}
							},
							isHidden: function(args) {
								if(isAdmin() || isDomainAdmin())
									return false;
								else
									return true;
							}
						},		
						
						account: { 
							label: 'Account',
							isHidden: function(args) {
								if(isAdmin() || isDomainAdmin())
									return false;
								else
									return true;
							}			
						}
            /*
						,
            startdate: {
              label: 'Start Date',
							isDatepicker: true
            },
            enddate: {
              label: 'End Date',
							isDatepicker: true
            }				
            */						
					},						
					
          dataProvider: function(args) {					  
						var data = {};
						listViewDataProvider(args, data);						
						
            $.ajax({
              url: createURL('listEvents'),
              data: data,              
              success: function(json) {
                var items = json.listeventsresponse.event;
                args.response.success({data:items});
              }
            });
          },
					detailView: {
            name: 'label.details',
              actions: {

              // Remove single event
              remove: {
                label: 'Delete',
                messages: {
                  notification: function(args) {
                    return 'Event Deleted';
                  },
                  confirm: function() {
                    return 'Are you sure you want to remove this event?';
                  }
                },
                action: function(args) {

                  $.ajax({
                       url:createURL("deleteEvents&ids=" +args.context.events[0].id),
                       success:function(json){  

                  args.response.success();
                             
                       }

                       });
                }
              },

              // Archive single event
              archive: {
                label: 'Archive',
                messages: {
                  notification: function(args) {
                    return 'Event Archived';
                  },
                  confirm: function() {
                    return 'Please confirm that you want to archive this event.';
                  }
                },
                action: function(args) {
                    
                  $.ajax({
                       url:createURL("archiveEvents&ids=" +args.context.events[0].id),
                       success:function(json){

                  args.response.success();        
                             
                       }

                       });
                  

                  // Reloads window with item archived
                  $(window).trigger('cloudStack.fullRefresh');
                }
              }
           },
            tabs: {
              details: {
                title: 'label.details',
                fields: [
                  {
									  description: { label: 'label.description' },
										state: { label: 'label.state' },
									  level: { label: 'label.level' },
                    type: { label: 'label.type' },										                
										domain: { label: 'label.domain' },
										account: { label: 'label.account' },
										username: { label: 'label.initiated.by' },
                    created: { label: 'label.date', converter: cloudStack.converters.toLocalDate },
										id: { label: 'label.id' }
                  }
                ],
                dataProvider: function(args) {								  
									$.ajax({
										url: createURL("listEvents&id=" + args.context.events[0].id),
										dataType: "json",
										async: true,
										success: function(json) {
											var item = json.listeventsresponse.event[0];
											args.response.success({data: item});
										}
									});									
								}
              }
            }
          }
        }
      },
      alerts: {
        type: 'select',
        title: 'label.menu.alerts',
        listView: {
          id: 'alerts',
          label: 'label.menu.alerts',
          fields: {
            description: { label: 'label.description' },
            type: {label:'Type'},
            sent: { label: 'label.date', converter: cloudStack.converters.toLocalDate }
          },

           actions: {
            // Remove multiple Alerts
            remove: {
              label: 'Delete Alerts',
              isHeader: true,
              addRow: false,
              messages: {
                notification: function(args) {
                  return 'Alerts Deleted';
                }
              },
              createForm: {
                title:'Delete Alerts',
                desc: '',
                fields: {
                  type: { label: 'By Alert type' , docID:'helpAlertsDeleteType'},
                  date: { label: 'By date (older than)' ,docID:'helpAlertsDeleteDate', isDatepicker: true }
                }
              },
             action: function(args) {

                var data={};

                if(args.data.type != "")
                  $.extend(data, { type:args.data.type });

                if(args.data.date != "")
                  $.extend(data, {olderthan:args.data.date });

                $.ajax({

                     url:createURL("deleteAlerts"),
                     data:data,
                     dataType:'json',
                     async: false,

                  success:function(data){

                  args.response.success();

                    }
                   });
                                  // Reloads window with events removed
                $(window).trigger('cloudStack.fullRefresh');
              }
            },
          
           // Archive multiple Alerts
            archive: {
              label: 'Archive Alerts',
              isHeader: true,
              addRow: false,
              messages: {
                notification: function(args) {
                  return 'Alerts Archived';
                }
              },
              createForm: {
                title:'Archive Alerts',
                desc: '',
                fields: {
                  type: { label: 'By Alert type', docID:'helpAlertsArchiveType' },
                  date: { label: 'By date (older than)' , docID:'helpAlertsArchiveDate', isDatepicker: true }
                }
              },
              action: function(args) {
                   var data={};

                if(args.data.type != "")
                  $.extend(data, { type:args.data.type });

                if(args.data.date != "")
                  $.extend(data, {olderthan:args.data.date });

                $.ajax({

                     url:createURL("archiveAlerts"),
                     data:data,
                     dataType:'json',
                     async: false,

                  success:function(data){

                  args.response.success();

                    }
                   });

                // Reloads window with events removed
                $(window).trigger('cloudStack.fullRefresh');
              }
            }

          },

          dataProvider: function(args) {
					  var data = {};
						listViewDataProvider(args, data);		
					
            $.ajax({
              url: createURL('listAlerts'),
              data: data,
              async: true,
              success: function(json) {
                var items = json.listalertsresponse.alert;
                args.response.success({data:items});
              }
            });
          },
          detailView: {
            name: 'Alert details',
              actions: {

              // Remove single Alert
              remove: {
                label: 'Delete',
                messages: {
                  notification: function(args) {
                    return 'Alert Deleted';
                  },
                  confirm: function() {
                    return 'Are you sure you want to delete this alert ?';
                  }
                },
                action: function(args) {

                  $.ajax({
                       url:createURL("deleteAlerts&ids=" +args.context.alerts[0].id),
                       success:function(json){

                  args.response.success();

                       }

                       });
                    $(window).trigger('cloudStack.fullRefresh');

                }
              },

               archive: {
                label: 'Archive',
                messages: {
                  notification: function(args) {
                    return 'Alert Archived';
                  },
                  confirm: function() {
                    return 'Please confirm that you want to archive this alert.';
                  }
                },
                action: function(args) {

                  $.ajax({
                       url:createURL("archiveAlerts&ids=" +args.context.alerts[0].id),
                       success:function(json){

                  args.response.success();

                       }

                       });


                  // Reloads window with item archived
                  $(window).trigger('cloudStack.fullRefresh');
                }
              }

            },  

            tabs: {
              details: {
                title: 'label.details',
                fields: [
                  {
                    id: { label: 'ID' },
                    description: { label: 'label.description' },
                    sent: { label: 'label.date', converter: cloudStack.converters.toLocalDate }
                  }
                ],
                dataProvider: function(args) {								  
									$.ajax({
										url: createURL("listAlerts&id=" + args.context.alerts[0].id),
										dataType: "json",
										async: true,
										success: function(json) {
											var item = json.listalertsresponse.alert[0];
											args.response.success({data: item});
										}
									});															 
								}
              }
            }
          }
        }
      }
    }
  };
})(cloudStack);
